React Tips — GraphQL Queries, URL Parameters and React Router

John Au-Yeung - Jan 25 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

Make GraphQL Queries with React Apollo

We can make GraphQL queries with React Apollo by using the client.query method.

This is available once we update the component by calling withApollo function.

For instance, we can write:

class Foo extends React.Component {
  runQuery() {
    this.props.client.query({
      query: gql`...`,
      variables: {
        //...
      },
    });
  }

  render() {
    //...
  }
}

export default withApollo(Foo);
Enter fullscreen mode Exit fullscreen mode

The client.query method will be available in the props once we call withApollo with our component to return a component.

The method takes an object that has the query and variables properties.

The query property takes a query object returned by the gql form tag.

variables has an object with variables that we interpolate in the query string.

We can also wrap our app with the ApolloConsumer component.

For example, we can write:

const App = () => (
  <ApolloConsumer>
    {client => {
      client.query({
        query: gql`...`,
        variables: {
          //...
        }
      })
    }}
  </ApolloConsumer>
)
Enter fullscreen mode Exit fullscreen mode

We can make our query in here.

For function components, there’s the useApolloClient hook.

For instance, we can write:

const App = () => {
  const client = useApolloClient();
  //...
  const makeQuery = () => {
    client => {
      client.query({
        query: gql`...`,
        variables: {
          //...
        }
      })
    }
  }
  //...
}
Enter fullscreen mode Exit fullscreen mode

The hook returns the client that we can use to make our query.

There’s also the useLazyQuery hook that we can use to make queries.

For instance, we can write:

const App = () => {
  const [runQuery, { called, loading, data }] = useLazyQuery(gql`...`)
  const handleClick = () => runQuery({
    variables: {
      //...
    }
  })
  //...
}
Enter fullscreen mode Exit fullscreen mode

runQuery lets us make our query.

React Router Pass URL Parameters to Component

We can pass URL parameters if we create a route that allows us to pass parameters to it.

For instance, we can write:

const App = () => {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/foo">foo</Link>
          </li>
          <li>
            <Link to="/bar">bar</Link>
          </li>
          <li>
            <Link to="/baz">baz</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/:id" children={<Child />} />
        </Switch>
      </div>
    </Router>
  );
}

function Child() {
  const { id } = useParams();

  return (
    <div>
      <h3>ID: {id}</h3>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

We have a Child component that has the useParams hook.

It lets us get the URL parameters that we want and it’s passed in from navigation.

It returns the URL parameter as a key-value pair.

The keys are what we defined and the value is what we have passed when we navigate.

In App , we have the Link components with the paths.

And also we have the Switch components that have the route that takes the id URL parameter.

The Route has the route that we pass in. children has the component that’s displayed.

Preventing Form Submission in a React Component

There are several ways to prevent form submission in a React component.

If we have a button inside the form, we can make set the button’s type to be button.

For instance, we can write:

<button type="button" onClick={this.onTestClick}>click me</Button>
Enter fullscreen mode Exit fullscreen mode

If we have a form submit handler function passed into the onSubmit prop;

<form onSubmit={this.onSubmit}>
Enter fullscreen mode Exit fullscreen mode

then in th onSubmit method, we call preventDefault to stop the default submit behavior.

For example, we can write:

onSubmit (event) {
  event.preventDefault();
  //...
}
Enter fullscreen mode Exit fullscreen mode

TypeScript Type for the Match Object

We can use the RouteComponentProps interface, which is a generic interface that provides some base members.

We can pass in our own interface to match more members if we choose.

For example, we can write:

import { BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom';

interface MatchParams {
  name: string;
}

interface MatchProps extends RouteComponentProps<MatchParams> {}

const App = () => {
  return (
    <Switch>
      <Route
         path="/products/:name"
         render={({ match }: MatchProps) => (
            <Product name={match.params.name}
         /> )}
      />
    </Switch>
  );
}
Enter fullscreen mode Exit fullscreen mode

We use the MatchProps interface that we created as the type for the props parameter in the render prop.

Then we can reference match.params as we wish.

Conclusion

We can make GraphQL queries in a React component with the React Apollo client.

React Router lets us pass in URL parameters easily.

It works with JavaScript and TypeScript.

We can prevent form submission with event.preventDefault() in the submit handler.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .