reactjsapollomutation

How to mutate with useMutation from Apollo


I have a graphQL query that give me all inputs to display in a form, and I have to use the same query to mutate database when there is an onChange event on an input.

I managed to make the query, and to display all my inputs.

Now, i'm having difficulties to find how I can resend my query with new value when a data is entered.

I need to send the specific id to make my backend understand that it has to mutate the existing article instead of creating a new one.

Any idea how to do this ?

Here is my form.service.tsx:

export const FORM = gql`
  mutation form($article: ArticleInput!) {
    form(annonce: $annonce) {
      article{
        id
      }
      formContent
    }
  }
`;

export const FormData = ({ children }) => {
  const [form, { data, loading, error }] = useMutation(
    form,
    {
      variables: {
        annonce: {
          idtype: 2,
          id: 0, // I need this to be dynamic
        },
      },
    },
  );

  useEffect(() => {
    form().then((res) => {
      if (res.data) {
        res.data.form.formContent = JSON.parse(
          res.data.form.formContent,
        );
      }
    });
  }, [form]);

  return children(data, loading, error);
};

Then I use this as a wrapper in form.tsx :

<FormData>
      {(data, loading) => {
        if (loading) return <>loading...</>;

        return (
          <>
            <Section3 dataToDisplay={data.groups} />

And finaly, in section3.tsx of my form :

const Section3 = ({ data }) => {
  const [typeDeBienSelected, setTypeDeBienSelected] = useState<Group>(
    data.find((item) => item.selected) ?? data[0],
  );

  return (
    <div className="hk-flex hk-flex-col hk-gap-8">
      <MyInputComponent
        list={typeDeBien ?? []}
        value={typeDeBienSelected}
        setValue={(e) => setTypeDeBienSelected(e)}
      />
  );
};

export default Section3;

Solution

  • As I understand you want to dynamically send the ID for mutation when an input value changes. Here is the steps you can follow to achieve this.

    Add State Variable in FormData Component

    In your FormData component, let's add a s state variable to track the id value and pass the setId function as a prop from FormData to Section3.tsx component.

    export const FormData = ({ children }) => {
      const [id, setId] = useState(0); // State variable to track the ID
    
      const [form, { data, loading, error }] = useMutation(
        FORM,
        {
          variables: {
            annonce: {
              idtype: 2,
              id: id, // Use the dynamic ID here
            },
          },
        },
      );
    
      useEffect(() => {
        form().then((res) => {
          if (res.data) {
            res.data.form.formContent = JSON.parse(
              res.data.form.formContent,
            );
          }
        });
      }, [form]);
    
      return children(data, loading, error, setId); // Pass the setId function as a prop
    };
    
    

    Update setValue function in Section3 Component

    In the Section3.tsx, update the setValue function to call the setId function and pass the new ID:

    const Section3 = ({ data, setId }) => {
      const [typeDeBienSelected, setTypeDeBienSelected] = useState(
        data.find((item) => item.selected) ?? data[0],
      );
    
      const handleInputChange = (newValue) => {
        setTypeDeBienSelected(newValue);
        setId(newValue.id); // Update the ID when the input value changes
      };
    
      return (
        <div className="hk-flex hk-flex-col hk-gap-8">
          <MyInputComponent
            list={typeDeBien ?? []}
            value={typeDeBienSelected}
            setValue={handleInputChange} // Pass the updated function here
          />
        </div>
      );
    };
    
    export default Section3;