Home > front end >  How to clear React Json Array with a custom input hook
How to clear React Json Array with a custom input hook

Time:01-22

I am a learning react and have hit a snag. I have created a custom hook to handle all my input which works fine but am having trouble clearing the form after submit. Here is my custom input hook.

export function useFormFields(initialState) {
  const [fields, setValues] = useState(initialState);

  return [
    fields,
    function(event) {
      try {
        const { name, value, type, checked } = event.target;
        setValues({
          ...fields,
          [name]: type === "checkbox" ? checked : value,
        });
      } catch (err) {
        console.log(err);       
      }
    },
  ];
}

This is how am calling the react hook in my component.

function NewMachine() {
  let data = {
    user_level:"",  
    name: "",
    email: "",
  };
  let [formData, setFormData] = useFormFields(data);
  const [reset, setReset] = useState(false)
   const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
    setFormData(data);//getting error here
  
  };
  return (
    <div>
    <form onSubmit={handleSubmit} autoComplete="off">
     <input
                      placeholder="Enter Name"
                      className="form-control"
                      id="name"
                      name="name"
                      onChange={setFormData}
                      required
                    />
                    ...>other fields
                          <button className="float-right btn btn-secondary" type="submit">
             
                Create New User
              </button>
    </form>
    </div>
    );

This is the error am getting enter image description here

CodePudding user response:

You're passing a object with the new values and it is expecting a React.ChangeEvent which has a target with the name, value, type, checked values.

Something you can do is check if the event is a actual React Event. If it is a actual event do your event.target stuff else just set the values.

return [
  fields,
  function (event) {
    if ("_reactName" in event) {
      // the check
      try {
        const { name, value, type, checked } = event.target;
        setValues({
          ...fields,
          [name]: type === "checkbox" ? checked : value,
        });
      } catch (err) {
        console.warn(err);
      }
    } else {
      setValues(event);
    }
  },
];

Note that currently the input has no value prop so when resetting the values it will not update the input.

return (
  <div>
    <form onSubmit={handleSubmit} autoComplete="off">
      <input
        placeholder="Enter Name"
        className="form-control"
        id="name"
        name="name"
        value={fields["name"]} // add this here
        onChange={onChange}
        required
      />
      <button className="float-right btn btn-secondary" type="submit">
        Create New User
      </button>
    </form>
  </div>
);

This is a way you could go but I recommend creating a reset function which you return from the hook to handle the resetting. Since we're returning multiple values we can return them as a object {} instead of a array, in case we don't need the reset in some other form.

function useFormFields(initialState) {
  const [fields, setValues] = useState(initialState);

  const reset = (newValues = initialState) => {
    setValues(newValues);
  };

  const onChange = (event) => {
    try {
      const { name, value, type, checked } = event.target;
      setValues({
        ...fields,
        [name]: type === "checkbox" ? checked : value,
      });
    } catch (err) {
      console.error(err);
    }
  };

  return { fields, onChange, reset };
}

Which you can use like

let { fields, onChange, reset } = useFormFields(data);
const handleSubmit = (e) => {
  e.preventDefault();
  console.log(fields);
  reset(data);
  // reset(); // or like this since the default values to reset to is the initialState
};
return (
  <div>
    <form onSubmit={handleSubmit} autoComplete="off">
      <input
        placeholder="Enter Name"
        className="form-control"
        id="name"
        name="name"
        value={fields["name"]}
        onChange={onChange}
        required
      />
      <button className="float-right btn btn-secondary" type="submit">
        Create New User
      </button>
    </form>
  </div>
);
  • Related