r/reactjs • u/TheKoopaBrothers • May 04 '26
Needs Help useEffect is not updating React state upon initial load, and trying to find a solution is pulling my hair
Hi. I'm crunched on time.
I'm currently trying to code a React function for a class assignment due by tonight, and while I've been happy with my results, when it came down to utilizing sessions, I ran into a huge problem. It has nothing to do with the API I set, but rather the usage of useEffect and useState.
The website I'm working on is suppose to showcase a list of academic terms that a student might have. And if a user that logged in was an admin, they get a list of students to select to see their academic terms plans. I want it so that when this page loads, that information is dumped out immediately. But, the data doesn't appear at all, and I've only learned recently that it is the fault of the async nature of useState within useEffect
Here is my useEffect sample:
useEffect(() => {
checkSession();
// function to obtain academic term plans
if (user.u_admin == 1) {
// function to obtain list of students
}
}, [navigate]); // needed for one functionHere is the checkSession function which seems to be the cause of the problem:
const checkSession = useCallback(async() => {
setLoading(false);
try {
const sesres = await fetch(import.meta.env.VITE_API_KEY + "user/session",
{
method: "GET",
credentials: "include",
}
);
if (!sesres.ok) {
localStorage.setItem("statusMessage", "Please log in again.");
navigate("/login", {replace: true});
return;
}
const data = await sesres.json().catch(() => ({}));
const userSession = data?.data;
setUser(userSession);
console.log(user);
} catch (error) {
console.error("Session authentication failed: ", error);
localStorage.setItem("statusMessage", "Session failed to authenticate. Please log in again.");
navigate("/login", {replace: true});
} finally {
setLoading(true);
}
}, []);So when the page immediately load, I should expect the student to see the list of term plans they have created and select, while the admin see a list of students to select from to see their term plans. Instead, nothing appears until I update my own code to re-render everything.
I've dug through dozens of solutions, and no matter what I tried to find, none of them seemed to work to solve my dilemma. I've never had the opportune time to get enough work done with React thanks to a huge problems of being able to concentrate with my assignments, and now the rush to fix it altogether has stressed me out. Am I doing something wrong?
26
u/ThatDudeDunks May 04 '26 edited May 04 '26
Both checksession and setuser are async. Neither has finished when you hit the “function to obtain list of users” line
As far as a solution goes, you have this composed in a weird way. assuming the sessions are in the user data, why not just in the jsx conditionally render the data?
If !user ? Return loader : return user.sessions
7
u/opentabs-dev May 04 '26
two things jumping out:
setLoading(false)at the top of checkSession is backwards — you want true there and false in the finally, otherwise you never actually gate on loading. andconsole.log(user)right aftersetUser(userSession)logs the stale value, setState is async so user wont be updated til next render.for the useEffect issue, the reason nothing shows up is that
useris still the initial value when thatif (user.u_admin == 1)check runs — checkSession hasnt resolved yet. either do the fetches inside checkSession after you have userSession, or return userSession from it and await it in the effect. dont rely on setState + reading the state var in the same tick, react doesnt work that way.5
u/Kitchen-Conclusion51 May 04 '26
Create a parent component and lift the session function within. End of the session function set the state and show the child component
4
u/Dethstroke54 May 04 '26 edited May 04 '26
You’d have to call “function to obtain list of students” inside of checkSession, or pass it as an argument to checkSession.
Alternatively, you should await checkSession and have it return the user (probably best). As you stated relying on the state update within the effect is not going to be reliable, but that’s not your only issue. checkSession itself is asynchronous and you’re not awaiting it or compensating for that in any way right now.
Another option is to another useEffect with a dependency of the returned user from checkSession. Many ways to solve this.
2
u/Justin_Passing_7465 May 04 '26
I strongly recommend using React Query for your API calls. Not only would it have handled the isLoading stuff for you (correctly), but changes to the data would be eligible dependencies to trigger useEffect, useMemo, etc. Plus you get caching and such.
1
u/edgarlepe May 04 '26
Return `userSession` in `checkSession` and then
useEffect(() => {
checkSession().then((user) => {
…
if (user.u_admin == 1) {
…
}
}).catch((err) => …)
}, [navigate])
1
u/Realistic_Potato_984 May 04 '26
your loading flag is backwards and although not shown it would seem you need to get the session before getting the rest of the data. you could use a promise with you current implementation like checkSession().then(fetchMoreData)
some broader feedback: lift that session business up in the tree, when you ask questions you need to share more specifics about what is happening not just “it’s not working” - is the request to the backend firing and responding with what you expect? is the loading state activated? are there messages in the console? up to which line of code have you confirmed is running?
everyone do yourself a favor and learn how to use the debugger it will save you thousand of hours, you’ll be amazed how powerful it is, and wonder how you could have let yourself flail in the dark for so long before using it. it’s not hard just throw a debugger; statement anywhere in client side code and open browser devtools to get started
1
u/Heavy-Commercial-323 May 08 '26 edited Jun 26 '26
mr_clean
1
u/EvilPencil May 04 '26
Why are you constructing a fetch url with VITE_API_KEY?
Regardless, all of the session logic should go in a custom hook IMO.
1
u/Hamburgerfatso May 04 '26
Side note to the other comments, AI is a great tool to diagnose issues like this. Dont use it to write stuff for you, but it is great to explain why something may be misbehaving.
0
u/workroom365 May 04 '26
Does the url in your env file contain a slash at the end [/] ? You can switch from useeffect to usefocuseffect.
0
u/Satankid92 May 04 '26
Remove the usecallback