reactjstypescriptgraphqlmaterial-uimutation

How can I mutation Material UI Input without save button?


I am trying to mutate without the save button. When the user writes/edits something on the input line, it should be saved in the graphql automatically. This code is working, but something weird. When I type "hello", it saves like four times like h, he, hel, hell, but It does not save hello when I query the product's name.

Please let me know if there is a better way.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

  // import { Button } from "@mui/material";
    import React, { useEffect, useRef, useState } from "react";
    // import TextField from "@material-ui/core/TextField";
    import EditIcon from "@material-ui/icons/Edit";
    // import CheckIcon from "@material-ui/icons/Check";
    import {
      FormControl,
      FormHelperText,
      Grid,
      Input,
      InputAdornment,
    } from "@material-ui/core";
    import { makeStyles } from "@material-ui/styles";
    import { gql, useMutation } from "@apollo/client";

    const CREATE_PRODUCT = gql`
      mutation AddProduct($name: String!) {
        addProduct( name: $name) {
          name
        }
      }
    `;

    const EditTextField = () => {
      const [inputText, setInputText] = useState<string>("");
      const [disabled, setDisabled] = useState<boolean>(true);

      const inputRef = useRef<HTMLInputElement>();

      const [AddProduct,{data, loading, error}] = useMutation(CREATE_PRODUCT, {
        variables:{
          name:inputText,
        }
      })

      return (
        <Grid container>
          <Grid item>
            <FormControl>
              <Input
                id="standard-adornment-weight"
                value={inputText}
                onChange={(e: any) => {setInputText(e.target.value);AddProduct()}}
                endAdornment={
                  <InputAdornment position="end">
                    <EditIcon />
                  </InputAdornment>
                }
              />
              <FormHelperText id="standard-weight-helper-text">
                Column Nmae
              </FormHelperText>
            </FormControl>
          </Grid>
        </Grid>
      );
    };

    export default EditTextField;


Solution

  • I would recommend to wrap your mutation in a useEffect hook, then call the useEffect when your input text changes.

    It would look like below:

    const [inputText, setInputText] = useState<string>("");
    
    useEffect(() => {
        AddProduct({ variables: { name: inputText } })
    }, [inputText]); /* useEffect triggered when inputText state changes. */