React Tips — GraphQL Queries, URL Parameters and React Router
Tags: react, webdev, programming, javascript
Published: 2021-01-25 01:44:54

**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);
```

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>
)
```

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: {
          //...
        }
      })
    }
  }
  //...
}
```

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: {
      //...
    }
  })
  //...
}
```

`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>
  );
}
```

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>
```

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

```
<form onSubmit={this.onSubmit}>
```

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

For example, we can write:

```
onSubmit (event) {
  event.preventDefault();
  //...
}
```

### 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>
  );
}
```

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.