javascriptreactjsreact-nativereact-hook-form

useFieldArray in react hook form is only deleting the last element


I'm having a trouble with react hook form useFieldArray.

I'm trying to append and delete but when I'm deleting it's deleting only the last element.

Append is working fine but suppose I have 3 fields with values A, B, C. I want to remove B, but when I press the remove button of B then it's removing C. If I try to remove A again it's also removing C only from the UI.

Here is my codesandbox link for the code: Codesandbox


Solution

  • I made some changes to your codesandbox and this should work:

    import React from "react";
    import { useForm, useFieldArray, Controller, useWatch } from "react-hook-form";
    import ReactDOM from "react-dom";
    // import Button from '@mui/material/Button';
    
    import "./styles.css";
    
    let renderCount = 0;
    
    function App() {
      const { register, control, handleSubmit, reset, watch } = useForm({
        defaultValues: {
          parameters: [{ parameterName: "" }]
        }
      });
    
      const {
        fields: parameterfields,
        append: appendParameters,
        remove: removeParameters
      } = useFieldArray({
        control,
        name: "parameters"
      });
    
      const onSubmit = (data) => console.log("data", data);
    
      // if you want to control your fields with watch
      // const watchResult = watch("test");
      // console.log(watchResult);
    
      // The following is useWatch example
      // console.log(useWatch({ name: "test", control }));
    
      renderCount++;
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <h1>Field Array </h1>
          <p>The following demo allow you to delete, append, prepend items</p>
          <span className="counter">Render Count: {renderCount}</span>
          <ul>
            {parameterfields.map((item, index) => {
              return (
                <div
                  key={item.id}
                  style={{ display: "flex", marginTop: 30 }}
                >
                  <div style={{ width: "90%", marginRight: 20 }}>
                    <Controller
                      name={`parameters.${index}.parameterName`}
                      control={control}
                      render={({ field: { onChange, value } }) => (
                        <div>
                          {console.log(item.parameterName)}
                          <input
                            name={`parameters[${index}].parameterName`}
                            variant="standard"
                            InputProps={{
                              disableUnderline: true
                            }}
                            // className={styles.title}
                            onChange={onChange}
                            defaultValue={item.parameterName}
                            placeholder="Parameter Name"
                          />
                        </div>
                      )}
                    />
                  </div>
                  <div>
                    <button
                      onClick={() => removeParameters(index)}
                      sx={{ width: 130, height: 50 }}
                      variant="outlined"
                    >
                      Remove
                    </button>
                  </div>
                </div>
              );
            })}
          </ul>
          <section>
            <button
              type="button"
              onClick={() => {
                appendParameters({ 
                  date: new Date(),
                  parameterName: "" });
              }}
            >
              append
            </button>
          </section>
    
          <input type="submit" />
        </form>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);