DEV Community

Ashish K Mishra
Ashish K Mishra

Posted on

Handle Multiple Queries & Mutations in React Form using Apollo Client

In this tutorial, we'll explore how to handle multiple queries and mutations in a controlled form using Apollo Client in a React application. We'll leverage Apollo Client to fetch data from a GraphQL API and update the form state based on user input. We'll also perform mutations to update the data in the database.

Prerequisites:

  • Basic knowledge of React and GraphQL
  • Familiarity with Apollo Client and controlled forms in React

Let's dive into the step-by-step process:

Step 1: Set up Apollo Client
Start by setting up Apollo Client in your React application. Install the required packages by running the following command in your project directory:

npm install @apollo/client graphql
Enter fullscreen mode Exit fullscreen mode

Next, create an instance of Apollo Client and configure it with the necessary details. In your index.js or App.js file, import the required dependencies:

import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
Enter fullscreen mode Exit fullscreen mode

Create the Apollo Client instance:

const client = new ApolloClient({
  uri: 'YOUR_GRAPHQL_ENDPOINT_URL',
  cache: new InMemoryCache(),
});
Enter fullscreen mode Exit fullscreen mode

Replace 'YOUR_GRAPHQL_ENDPOINT_URL' with the actual GraphQL API endpoint URL.

Step 2: Define GraphQL Queries
Identify the data you need for your form and write the GraphQL queries to fetch that data. For example, let's assume we have a form that requires fetching a list of countries and a user's profile.

Define the GraphQL queries using the gql tag from the graphql package. Here's an example of querying countries:

import { gql } from '@apollo/client';

const GET_COUNTRIES = gql`
  query GetCountries {
    countries {
      id
      name
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

Similarly, define a query to fetch a user's profile:

const GET_USER_PROFILE = gql`
  query GetUserProfile($userId: ID!) {
    user(id: $userId) {
      id
      name
      email
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Form Component
Build a React form component that includes the necessary input fields. In this example, we'll use a controlled form approach, where the form fields are controlled by React state.

Import the necessary dependencies and hooks:

import React, { useState } from 'react';
import { useQuery, useMutation } from '@apollo/client';
Enter fullscreen mode Exit fullscreen mode

Create the form component:

const MyForm = () => {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    countryId: '',
  });

  const { loading: countriesLoading, error: countriesError, data: countriesData } = useQuery(GET_COUNTRIES);
  const { loading: userProfileLoading, error: userProfileError, data: userProfileData } = useQuery(GET_USER_PROFILE, {
    variables: { userId: 'USER_ID' }, // Replace with the actual user ID
  });

  const [updateUserProfile] = useMutation(UPDATE_USER_PROFILE);

  const handleInputChange = (event) => {
    const { name, value } = event.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value,
    }));
  };

  const handleSubmit = (event) => {
    event.preventDefault();

    const { name, email, countryId } = formData;

    // Execute the mutation
    updateUserProfile({ variables: { userId: 'USER

_ID', name, email, countryId } })
      .then((response) => {
        // Handle success
      })
      .catch((error) => {
        // Handle error
      });
  };

  if (countriesLoading || userProfileLoading) {
    return <div>Loading...</div>;
  }

  if (countriesError || userProfileError) {
    return <div>Error fetching data.</div>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" name="name" value={formData.name} onChange={handleInputChange} />
      </label>
      <label>
        Email:
        <input type="email" name="email" value={formData.email} onChange={handleInputChange} />
      </label>
      <label>
        Country:
        <select name="countryId" value={formData.countryId} onChange={handleInputChange}>
          <option value="">Select a country</option>
          {countriesData.countries.map((country) => (
            <option key={country.id} value={country.id}>
              {country.name}
            </option>
          ))}
        </select>
      </label>
      <button type="submit">Submit</button>
    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

Replace 'USER_ID' with the actual user ID.

Step 4: Perform Mutations on Form Submission
Define the GraphQL mutations required to update or create data in the database. For example, let's assume we have a mutation to update a user's profile.

Define the GraphQL mutation using the gql tag:

const UPDATE_USER_PROFILE = gql`
  mutation UpdateUserProfile($userId: ID!, $name: String!, $email: String!, $countryId: ID!) {
    updateUser(id: $userId, name: $name, email: $email, countryId: $countryId) {
      id
      name
      email
      countryId
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

In the form component, import the necessary dependencies:

import { useMutation } from '@apollo/client';
Enter fullscreen mode Exit fullscreen mode

Handle form submission and execute the mutation:

const MyForm = () => {
  // ...

  const handleSubmit = (event) => {
    event.preventDefault();

    const { name, email, countryId } = formData;

    // Execute the mutation
    updateUserProfile({ variables: { userId: 'USER_ID', name, email, countryId } })
      .then((response) => {
        // Handle success
      })
      .catch((error) => {
        // Handle error
      });
  };

  // ...
};
Enter fullscreen mode Exit fullscreen mode

Replace 'USER_ID' with the actual user ID.

Step 5: Conclusion
In this tutorial, we learned how to handle multiple queries and mutations in a controlled form using Apollo Client in a React application. We set up Apollo Client, defined GraphQL queries to fetch data, created a controlled form component to handle user input, performed mutations on form submission, and updated the form state accordingly. By leveraging Apollo Client and controlled forms in React, we can easily manage complex form interactions and data flow in our applications.

Remember to replace 'YOUR_GRAPHQL_ENDPOINT_URL' and 'USER_ID' with your actual GraphQL API endpoint URL and user ID, respectively.

Top comments (4)

Collapse
 
renanfranca profile image
Renan Franca

Awesome work, Ashish! πŸŽ‰πŸ‘ Your step-by-step guide is a beacon of clarity in the world of Apollo Client and React. This post is not only informative, but it's also well-structured, making it easy for both beginners and experienced developers to follow. Keep lighting the way! πŸš€πŸ’‘πŸŒŸ

Collapse
 
ashishkmishra36 profile image
Ashish K Mishra

Thanks Renan for the appreciation .

Collapse
 
dilutewater profile image
Rachit Khurana

This is an awesome article, a few days ago I wanted some data from a graphql api, but I didn't knew how to use it. I didn't knew it was this easy

Collapse
 
ashishkmishra36 profile image
Ashish K Mishra

Thanks Rachit , it helped you.