0

So I have this component which is used for forms handling:

import React, { useState } from "react";

export const useForm = (callback: any, initialState = {}) => {
  const [values, setValues] = useState(initialState);

  const onChange = (event: React.ChangeEvent<any>) => {
    setValues({ ...values, [event.target.name]: event.target.value });
  };

  const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    await callback();
  };

  return {
    onChange,
    onSubmit,
    setValues,
    values,
  };
}

in my component, I use it like this:

const { id } = useParams();

  const initialState = {
    field1: "",
    field2: "",
....
  }

  const { onChange, onSubmit, setValues, values } = useForm(
    submitData,
    initialState
  );

  useEffect(
    () => {
      if(id) {
        getData().then((response) => {
          setValues(response);
          console.log(response);
          console.log(values);
        });
      }
    }
  ,[]);

async function getData() {
    return await (await instance.get(url)).data;
  }

The two console.logs in the useEffect hook are different and I don't understand why. I used setValues so I expect the components to be re-drawn and the "values" variable to be updated with the values from the response, but it still has the values from the initialState for some reason.

Why is that happening and how can I fix it?

Octavian Niculescu
  • 1,177
  • 1
  • 3
  • 24
  • 1
    Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – David Sep 27 '22 at 12:08
  • @David it helped me understand things better, but how may I fix this problem? – Octavian Niculescu Sep 27 '22 at 12:13
  • Is there even a problem to fix? The observation made in the question is that `console.log(values)` outputs an unexpected result. But this turns out to be expected and correct behavior. The value to output in that case is `response`, which is observed to be correct. What problem remains? – David Sep 27 '22 at 12:14
  • I meant how can I see the values properly. but I did it. Thanks for your time :) – Octavian Niculescu Sep 27 '22 at 12:16

1 Answers1

1

The change of state using setState hook will not be reflected synchronously.
This is taken from react docs:

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied.

MrBens
  • 1,227
  • 1
  • 9
  • 19
  • I added another useEffect hook like this, without second parameters (so it acts as componentDiDupdate too) and it worked. useEffect( () => { console.log(values); } ); – Octavian Niculescu Sep 27 '22 at 12:15