Home > Software engineering >  Cannot clear state and getting wrong response from useState form
Cannot clear state and getting wrong response from useState form

Time:10-29

I'm strugling with my form in typescript react. Basicly I created 2 simple components Button and Input and add them to the another component Form where I created a whole form.

After submit I should get something like this:

telephone: "323423234"
email: "[email protected]"
message: "weklfnwlkf"
name: "less"
surname: "mess"

But after submit I get weird response like this:

"": "323423234"
email: "[email protected]"
message: "weklfnwlkf"
name: "less"
surname: "mess"
telephone: ""

It is a little bit werido because I done something like this couple days ago and now idk what to do. There is sample of my Form code

const Form = () => {
  interface FormDataType {
    telephone: string;
    name: string;
    surname: string;
    email: string;
    message: string;
  }
  const formData: FormDataType = {
    telephone: '',
    name: '',
    surname: '',
    email: '',
    message: '',
  };
  const [responseBody, setResponseBody] = useState<FormDataType>(formData);

  const clearState = () => {
    setResponseBody({ ...formData });
  };

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target;
    setResponseBody({ ...responseBody, [name]: value });
  };
  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(responseBody);
    clearState();
  };

  return (
    <>
      <form onSubmit={handleSubmit}>
        {FormData.map((option) => (
          <Input
            key={option.name}
            label={option.label}
            type={option.type}
            className={option.className}
            name={option.name}
            onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
              handleChange(e)
            }
          />
        ))}
        <div className='div'>
          <Button
            type='submit'
            title={'Simple test'}
            className={'btn-primary'}
          />
        </div>
      </form>
    </>
  );
};
export default Form;

And when I'm invoking in handleSubmit function clearState() it doesn't refresh states in webpage inputs.

CodePudding user response:

I hope this is what it needs, I made some changes, but you can adapt it to your project

export default function App() {
  interface FormDataType {
    telephone: string;
    name: string;
    surname: string;
    email: string;
    message: string;
  }
  const formData: FormDataType = {
    telephone: "",
    name: "",
    surname: "",
    email: "",
    message: ""
  };

  const [values, setValues] = useState<FormDataType | any>(formData);

  // reset
  const reset = (newFormState = formData) => {
    setValues(newFormState);
  };

  // handleInputChange
  const handleInputChange = ({ target }: any) => {
    setValues({ ...values, [target.name]: target.value });
  };

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(values);
    reset();
  };

  const data = [
    {
      type: "text",
      name: "name"
    },
    {
      type: "text",
      name: "surname"
    },
    {
      type: "email",
      name: "email"
    },
    {
      type: "tel",
      name: "telephone"
    },
    {
      type: "text",
      name: "message"
    }
  ];

  return (
    <>
      <form onSubmit={handleSubmit}>
        {data.map((option) => (
          <input
            key={option.name}
            value={values[option.name]}
            type={option.type}
            name={option.name}
            placeholder={option.name}
            onChange={handleInputChange}
          />
        ))}
        <div className="div">
          <button type="submit">Simple test</button>
        </div>
      </form>
    </>
  );
}

CodePudding user response:

Your reset doesn't work because your inputs are uncontrolled.

To have them reset properly, you should make them controlled by passing them a value prop. It would look something like this:

<Input
  key={option.name}
  label={option.label}
  type={option.type}
  className={option.className}
  name={option.name}
  value={responseBody[option.name]} // Add this
  onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
    handleChange(e)
  }
/>

This will connect the responseBody form data with the input values.

As to the odd console logged value, it would appear that at least one of the option.name values is empty/undefined (looks like the telephone object). Verify that the FormData contains complete and correct values.

  • Related