skip to Main Content

I need help understanding why is that the state is updated in the React Developer Tools state, but not when i console.log it.
Below is the code:

const [values, setValues] = useState({
    lastName: "",
    firstName: "",
    lastNameHiragana: "",
    firstNameHiragana: "",
    birthday: "",
    sex: "男",
    telephone: "",
    email: "",
    enterDate: "",
    companyId: "securityInt(SECI)",
    departmentId: "dev",
    commissionStatusId: "somestring",
    houseStatusId: "somestring",
    businessManager: "",
  });


  const onChange = (e) => {
    setValues({ ...values, [e.target.name]: e.target.value });
  };

  const handleForm = (e) => {
    e.preventDefault();

    const data = {
      firstName: values.firstName,
      lastName: values.lastName,
      firstNameHiragana: values.firstNameHiragana,
      lastNameHiragana: values.lastNameHiragana,
      companyId: values.companyId,
      birthday: values.birthday,
      sex: values.sex === "somestring" ? 0 : 1,
      mail: values.email,
      telephone: values.telephone,
      enterDate: values.enterDate,
      departmentId: values.departmentId,
      commissioningStatusId: values.commissionStatusId === "somestring" ? 0 : 1,
      houseStatusId: values.houseStatusId,
      businessManager: values.businessManager,
    };

    const newErrorMessage = {};
    const refresh_token = localStorage.getItem("refresh_token");
    const headers = {
      headers: {
        Authorization: `Bearer ${refresh_token}`,
      },
    };

    for (const name in values) {
      const hiraganaRegex = /^[ぁ-ん]+$/;
      const telephoneRegex = /^[0-9]{9,11}$/;
      const emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,4}$/;

      switch (name) {
        case "lastName":
        case "firstName":
        case "birthday":
        case "enterDate":
          if (!values[name]) {
            newErrorMessage[name] = "必須項目です";
          }
          break;

        case "lastNameHiragana":
        case "firstNameHiragana":
          if (!values[name]) {
            newErrorMessage[name] = "必須項目です";
          } else if (!hiraganaRegex.test(values[name]) && values[name]) {
            newErrorMessage[name] = "ひらがなで入力して下さい。";
          }
          break;

        case "telephone":
          if (!values[name]) {
            newErrorMessage[name] = "必須項目です";
          } else if (!telephoneRegex.test(values[name]) && values[name]) {
            newErrorMessage[name] = "9~11桁の半角数字で入力して下さい";
          }
          break;

        case "email":
          if (!values[name]) {
            newErrorMessage[name] = "必須項目です";
          } else if (!emailRegex.test(values[name]) && values[name]) {
            newErrorMessage[name] = "メールアドレスの形式が正しくありません";
          }
          break;
      }
    }
    if (!Object.keys(newErrorMessage).length) {
      // Get companies ID
      const fetchData = async () => {
        if (
          typeof values.companyId === "string" &&
          typeof values.departmentId === "string"
        ) {
          const [companyRes, departmentRes] = await Promise.all([
            axiosInstance.get("/company"),
            axiosInstance.get("/department"),
          ]);

          const company = values.companyId.slice(
            0,
            values.companyId.indexOf("(")
          );
          const findCompany = companyRes.data.result.find(
            (item) => item.name === company
          );
          const findDepartment = departmentRes.data.result.find(
            (item) => item.name === values.departmentId
          );
          console.log(values.companyId);
          console.log(values);
          setValues((prevValues) => ({
            ...prevValues,
            companyId: findCompany.id,
            departmentId: findDepartment.id,
          }));
          console.log(values.companyId);
        }
      };

      // Send the information to server
      const sendData = async () => {
        try {
          const response = await axiosInstance.post("/employee", data, {
            headers: headers,
          });

          console.log(response);
        } catch (error) {
          console.log(error);
        }
      };

      // Call the functions in sequence
      (async () => {
        await fetchData();
        await sendData();
      })();
    }

    setErrorMessage(newErrorMessage);
  };

I need to send the correct companyId and departmentID, which is OK when I check React Developer Tools state, but when I console.log the values, it gives me not the desired result.
Is the below not working, why?

setValues((prevValues) => ({
       ...prevValues,
       companyId: findCompany.id,
       departmentId: findDepartment.id,
}));

Is there anything wrong with the code?
Any input would be helpful.

Thank you in advance.

2

Answers


  1. The “useState” set method is asynchronous, hence, the updates are not reflected immediately. You can read this for more clarity.

    Since you are using hooks, in your case you need to useEffect hook to see the actual value in the state. You can follow this answer

    Login or Signup to reply.
  2. This behavior happens because the setValues function from useState in React is asynchronous. This means it does not immediately alter the state, but schedules the update to happen on the next render. Hence, you can’t rely on the state change to be instantaneous and console.log it right away.

    The fact that the new state shows up correctly in the React Developer Tools but not in the console.log is because the React Dev Tools read the state after all updates and re-renders have been completed, while your console.log statement is executing before the state has been updated.

    In your case, you are trying to log values right after calling setValues:

    setValues((prevValues) => ({
        ...prevValues,
        companyId: findCompany.id,
        departmentId: findDepartment.id,
    }));
    console.log(values.companyId);
    

    Since setValues is asynchronous, values has not been updated by the time console.log(values.companyId); runs.

    To handle this situation, you might consider using useEffect. useEffect can be used to perform side effects in function components, and it can be used to perform an action when a certain value changes. Here’s how you might use it:

    useEffect(() => {
      console.log(values.companyId);
    }, [values.companyId]); // This effect runs whenever `values.companyId` changes
    

    This useEffect hook will log the companyId whenever it changes, ensuring you’re always logging the latest value.

    Additionally, your sendData function is using the data object that was defined before fetchData was called and the state was updated. You should move the definition of data into the sendData function to ensure it uses the updated state:

    const sendData = async () => {
      const data = {
        firstName: values.firstName,
        lastName: values.lastName,
        firstNameHiragana: values.firstNameHiragana,
        lastNameHiragana: values.lastNameHiragana,
        companyId: values.companyId,
        birthday: values.birthday,
        sex: values.sex === "somestring" ? 0 : 1,
        mail: values.email,
        telephone: values.telephone,
        enterDate: values.enterDate,
        departmentId: values.departmentId,
        commissioningStatusId: values.commissionStatusId === "somestring" ? 0 : 1,
        houseStatusId: values.houseStatusId,
        businessManager: values.businessManager,
      };
    
      try {
        const response = await axiosInstance.post("/employee", data, {
          headers: headers,
        });
    
        console.log(response);
      } catch (error) {
        console.log(error);
      }
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search