0

I receive data back OK from the server with Axios, but when I try to set the state with the response data, the state won't update. The state is stored in context provider file, but I've tried state in the function itself with no luck either.

It is not a problem with the state itself, or the context provider as it works for other things.

What am I doing wrong? If anyone can advise please? Any help would be gratefully appreciated/acknowledged. Thanks.

const CheckUser = async () => {

  // state from the context file
  const { validUser,  setValidUser } = useContext(UserContext);
  


  useEffect(() => {
    axios
      .post(
        `${serverURL}/checkuser`,
        { someData: 1 },

        {
          withCredentials: true,
          credentials: 'include',
        }
      )
      .then((response) => {
        if (response.data) {
        
          // this will log the result fine:
          console.log(response.data.validUser); 
          
          // but the state won't update with it:
          setValidUser(response.data.validUser);
          
        } else {
          console.log('Failed to get data');
        }
      });
  }, []);
James
  • 106
  • 7
  • What do you mean by "won't update"? How are you testing that the state changes? With a `console.log` outside the `useEffect` hook? – cbr Oct 11 '20 at 17:20
  • console.logging it in the useEffect hook shows nothing. C.logging it outside the useEffect returns the empty result followed by the new result several times (repeats it a few times). Which ultimately is a good thing, however, I need it to return the correct data just once, because another component conditionally redirects to a signIn page. But because the validUser state is, at some point, not true, it redirects them to the sign in page before it managed to update to true. Does that make sense? – James Oct 11 '20 at 17:33
  • Yes, the change to `validUser` will not be reflected immediately after the call to `setValidUser`. The answers to these questions explain why: [Why calling react setState method doesn't mutate the state immediately?](https://stackoverflow.com/q/30782948/996081), [useState set method not reflecting change immediately](https://stackoverflow.com/q/54069253/996081). – cbr Oct 11 '20 at 17:37
  • So you'll probably want to have a `isLoading` state so that you can distinguish "is not valid user" from "haven't finished checking whether is valid user", and redirect only _after_ the loading is done. Otherwise you'll probably want to display a loading indicator of some sort. – cbr Oct 11 '20 at 17:38
  • OK, thanks for linking that thread. That thread seems to be focussed on class-based components. I like the sound of your isLoading state, but how would I implement that? I'm trying now, but unsure how to design it. – James Oct 11 '20 at 19:01
  • Just add `const [loading, setLoading] = useState(true)`, then in your `useEffect` after `setValidUser(...)` do `setLoading(false)`. And finally, after the `useEffect` hook before you return the actual JSX that you want to render, just add `if (loading) { return

    Loading

    }`.
    – cbr Oct 11 '20 at 19:02
  • And yes, the first link is about class components, the second link is about the useState hook. – cbr Oct 11 '20 at 19:03
  • Thank you! I see what you're saying. I will read the second link, sorry I didn't figure there was 2 links. I have just noticed that my app is forcing the initial validUser state value through before the state gets updated by my function pasted above because of a NavLink in which my sign-in request is made. So the cookie to validate the user was never there when the initial state was set. Hard to explain it in text, but long story short - NavLink was redirecting my page before the state was updated. Thanks again cbr. – James Oct 11 '20 at 19:20

0 Answers0