How to make a form for add and edit with Reack-hook-form

Viewed 23

I am trying to create a single form able to manage the creation of a product but also to edit it (by passing the values through an object).

The form works perfectly to create a product but how to make it able to edit a product?

I tried to pass my values via "value" or "defaultValue" but it seems to be a problem with the creation of a product (The values are as saved) The idea of creating a second form with default values passed in doesn't seem right

All this to create a basic CRUD.

Here is my form, I use Material-UI for the form elements, especially for its modal

    export default function App() {
  // ReactHookForm
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();


  
  const [Produits, setProduits] = useState([]);

  
  const [openAjout, setOpenAjout] = useState(false);
  const [openModif, setOpenModif] = useState({open: false, produit: null});
  const [openSuppr, setOpenSuppr] = useState({open: false, produitId: null});

  // Load product.
  const Chargement = async () => {
    const res = await fetch(`${ENDPOINT}/api/produits`);
    const data = await res.json();
    setProduits(data);
  };

  // create new product.
  const onSubmit = async (data) => {
    const re = await axios.post(`${ENDPOINT}/api/produits`, data, {
      headers: { 'Content-Type': 'application/json'}
    })
    setProduits([...Produits, data])
  };

  // edit product.
  const onSubmitUpdate = async (data) => {
    console.log('data', data)
    // const re = await axios.put(`${ENDPOINT}/api/produits/${data}`, data, {
    //   headers: { 'Content-Type': 'application/json'}
    // })
  };

  // delete product.
  const confirmSuppr = async (data) => {
    setOpenSuppr({open: false, produitId: data});
    const re = await axios.delete(`${ENDPOINT}/api/produits/${data}`, data, {
      headers: { 'Content-Type': 'application/json'}
    })
    setProduits(prevState => {
      prevState.filter(Produits => {
        return Produits.pro_id !== data;
      })
    });
  }

  // -- Handler open / close Dialogs
  // Handlers des Dialogs
  const handleAjout = (Bool) => {
    setOpenAjout(Bool);
  };

  const handleModif = (Bool, Produit) => {
    setOpenModif({open: Bool, produit: Produit});
  };

  const handleSuppr = (Bool, ProduitID) => {
    setOpenSuppr({open: Bool, produitId: ProduitID});
  };


  // Rendering
  useEffect(() => {
    Chargement();
  }, []);

  return (
    <div>
      <TableContainer component={Paper}>
        <Table>
          <TableHead>
            <TableRow style={{ background: "#cad2c5" }}>
              <TableCell align="center">{"ID"}</TableCell>
              <TableCell align="center">{"Nom"}</TableCell>
              <TableCell align="center">{"Description"}</TableCell>
              <TableCell align="center">{"Instruction"}</TableCell>
              <TableCell align="center">{"Prix"}</TableCell>
              <TableCell align="center">{"Action"}</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {Produits?.map((produit) => (
              <TableRow key={`PRO_${produit.pro_id}`}>
                <TableCell align="center">{produit.pro_id}</TableCell>
                <TableCell align="center">{produit.pro_nom}</TableCell>
                <TableCell align="center">{produit.pro_description}</TableCell>
                <TableCell align="center">{produit.pro_instruction}</TableCell>
                <TableCell align="center">{produit.pro_prix}{' €'}</TableCell>
                <TableCell align="center">
                  <Tooltip title="Modifier" placement="top">
                    <IconButton
                      style={{
                        background: "#ffca3a",
                        color: "white",
                        borderRadius: "10%",
                      }}
                      onClick={() => handleModif(true, produit)}
                    >
                      <EditIcon />
                    </IconButton>
                  </Tooltip>
                  <Tooltip title="Supprimer" placement="top">
                    <IconButton
                      style={{
                        background: "#ff595e",
                        color: "white",
                        borderRadius: "10%",
                      }}
                      onClick={() => handleSuppr(true, produit.pro_id)}
                    >
                      <DeleteIcon />
                    </IconButton>
                  </Tooltip>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>

      <Grid>
        <Button
          variant="contained"
          endIcon={<AddIcon />}
          onClick={() => handleAjout(true)}
        >
          {"Ajouter"}
        </Button>

        {/**
         * Dialog add product
         */}
        <Dialog open={openAjout} onClose={() => handleAjout(false)}>
          <DialogTitle>{"Ajout d'un produit"}</DialogTitle>
          <form onSubmit={handleSubmit(onSubmit)}>
            <DialogContent>
              <TextField
                type={"text"}
                name="pro_nom"
                {...register("pro_nom", { required: true })}
                label="Nom"
                placeholder="Hamburger"
                autoFocus
                variant="outlined"
              />
              {errors.pro_nom && <span>Champ requis.</span>}

              <TextField
                type={"text"}
                name="pro_description"
                {...register("pro_description", { required: true })}
                label="Description"
                placeholder="Description du produit"
                variant="outlined"
              />
              {errors.pro_description && <span>Champ requis.</span>}

              <TextField
                type={"text"}
                name="pro_instruction"
                {...register("pro_instruction")}
                label="Instruction"
                placeholder="Instruction particulière"
                variant="outlined"
              />

              <TextField
                type={"number"}
                name="pro_prix"
                {...register("pro_prix", { required: true, min: 0,  valueAsNumber: true })}
                label="Prix"
                placeholder="Obligatoire"
                variant="outlined"
              />
              {errors.pro_prix && <span>Champ requis.</span>}
            </DialogContent>
            <DialogActions>
              <Button type="reset">{"Effacer"}</Button>
              <Button onClick={() => handleAjout(false)}>{"Fermer"}</Button>
              <Button type="submit">{"Confirmer"}</Button>
            </DialogActions>
          </form>
        </Dialog>

1 Answers

There is a usefule function in react-hook-form called reset. It allows you to predefine the values for the form. Click here to see the documentation.

You just need to call it inside the useEffect hook and specify the fields. But before that you need to specify a state to check if it is an "add" or "edit" action.

const [action, setAction] = useState();

useEffect(() => {
  if(action == "edit"){
    reset({
      pro_description: "pro_description",
      pro_instruction: "pro_instruction"
    })
  }else if(action == "add"){
    reset({
      pro_description: "",
      pro_instruction: ""
    })
  }
  
}, [reset, action])
Related