Monday, 26 July 2021

React force update

I always run into situations where I need to force rerender, while I'm still in the execution of some function, so I developed my solution to this and I need to know if this is right or there is a simpler way to achieve the same goal.

I rely on the state variable my_force_update, then I change it to a random value when I want to enforce a change. like:

const [my_force_update, setMyForceUpdate] = useState(0);

useEffect(()=>{}, [my_force_update]);

const handleSubmit =  async () =>{
     await prm1();
     stMyForceUpdate(Math.random()); // enforcing the effect
     await prom2();
     ....
}

so I have been able to enforce re-render (by enforcing the effect) while I'm still in the handleSubmit execution.

is there a simpler way? or, did I mistakenly understand the concepts of React?

update

The issue is that I have a checkout form, and I need it to be a signup form at the same time, and there is also a login component on the page.

so I need to populate the form fields with the account if information in case of login and in case of sign up.

The steps are as follow:

if user login => populate form (per fill it with user info) => move to payment.

if user fill out the form manually:

  1. create an account.
  2. authenticate the new user.
  3. update the user account.
  4. repopulate form (with data from user account).
  5. move to payment.

so I have this function that needs to listen to the login and signup:

  const token = useSelector(_token);
  const loggedIn = useSelector(_loggedIn);
  const profile = useSelector(_profile);

  useEffect(() => {
    /**
     * Pre-fill the form inputs
    */
    (async () => {
      const r = await dispatch(fetchUserInfo());
      setFormProfile(profile); // address is not updated yet
      setFormAddress(r?.result?.address);
    })();
  }, [loggedIn, forceUpdate]);

now, there are no issues with the login process, the only problem is with the signup:

  1. at step 2, when authenticating the user, its account is empty.
  2. so the loggedIn changes to true when the profile is empty so I got empty form.
  3. after updating the profile, loggedIn will not change, so I need another variable to trigger the effect again.

I tried to listen to profile here, but I got an infinite loop.

and here is the checkout flow related to the signup:

...

 if (!loggedIn) {
      const signupResponse = await dispatch(signupUser(params));
      loginResponse = await dispatch(login(formProfile?.email, password));

    }

   const updateProfileResponse =  await saveChangesToProfile(); 
// update user profile with the information in the checkout form.

...


then save changes to the profile:


  const saveChangesToProfile = async () => {
    const r = await dispatch(fetchUserInfo());
    const addressID = r?.result?.address_id;

    const res1 = await dispatch(updateUserAddress(addressID, { ID: addressID, ...formAddress }));

    const res = await dispatch(UpdateUser(r?.result?.ID, formProfile));

    setForceUpdate(Math.random()); // force re-render to re-populate the form. 

    setSuccess("Information saved to your profile!");

    return res;
  };

Update 2

The question is general, I solved the issue in another way days ago (involving changes to the server routes). and I'm asking the question in a general way to get some knowledge, not for others to do the work for me.



from React force update

No comments:

Post a Comment