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:
- create an account.
- authenticate the new user.
- update the user account.
- repopulate form (with data from user account).
- 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:
- at step 2, when authenticating the user, its account is empty.
- so the
loggedIn
changes to true when theprofile
is empty so I got empty form. - 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.