0

old Title : React useEffect doesn't run on page reload

useEffect(()=>{console.log("I ran")}, []) // should run once

It does run if I navigate to the page that contains the component, but doesn't run again if I reload the page.

How do I get the effect to run even if I reload the page ? Edit: Reloading the page means to me pressing F5

Full Component

const Lobby = () => {
  const [result, setResult] = useState();

  const { joinedLobby, setCurJoinedLobby } = useContext(JoinedLobbyContext);

  useEffect(() => {
    if (joinedLobby !== undefined)
      sessionStorage.setItem('joinedLobby', JSON.stringify(joinedLobby));

    const storedJoinedLobby =
      sessionStorage.getItem('joinedLobby') !== null
        ? JSON.parse(sessionStorage.getItem('joinedLobby'))
        : undefined;

    if (joinedLobby === undefined && storedJoinedLobby !== undefined) {
      setCurJoinedLobby(storedJoinedLobby);
    }

    if (joinedLobby === undefined) return setResult(<div>Bad Link</div>);

    setResult(<div>Some stuff here</div>);
  }, []); // will be [joinedLobby] in the future

  return <div>{result}</div>
};

CodeSandbox

Cut down example, clone and run locally to get session store

Community
  • 1
  • 1
Twiggeh
  • 1,030
  • 1
  • 12
  • 24
  • Are you sure the same component is rendered once you refresh the screen? Can you please post the whole component, maybe the routing what you have and the **URL** what you try to refresh from your browser? Thanks! – norbitrial May 20 '20 at 10:52
  • After reloading, component will be mounted again i.e useEffect will run again. – Utsav Patel May 20 '20 at 10:54
  • @MohitMutha F5 type of reload – Twiggeh May 20 '20 at 11:00
  • @norbitrial I'll try to cut it down – Twiggeh May 20 '20 at 11:01
  • @DennisVash how would I show that ? Record a video ? – Twiggeh May 20 '20 at 11:05
  • Reproducing the behavior on codesandbox.io is one option of many – Dennis Vash May 20 '20 at 11:07
  • @DennisVash codesandbox blocks session store, thats why I didn't copy paste it to there – Twiggeh May 20 '20 at 11:17
  • Reloading your page should definitely trigger the `JavaScript` code to execute again and start your `React` app from the beginning, which triggers the `useEffect` hook. I think you're unclear what you mean by "reloading." – goto May 20 '20 at 11:19
  • I don't see how it's related to the session storage, you asking how to run on page refresh and it does. – Dennis Vash May 20 '20 at 11:22
  • I just tried your `CodeSandbox` and it works fine on every refresh after getting rid of the rest of the code that was inside the `useEffect` - what makes you think the `useEffect` doesn't run when you hit refresh? You have an early `return` that perhaps makes you think that it doesn't run but some of the conditions you've set are preventing it from running everything inside that hook. – goto May 20 '20 at 11:27
  • @DennisVash It has everything to do with it. I am setting state that is used by the component in that useEffect, and without that state the Component will throw. When I navigate through react router to that component it runs useEffect before trying to render the component, when I reload the page it doesn't. – Twiggeh May 20 '20 at 11:28
  • @DennisVash I just realized the effect runs after the render ... I guess to get what I want is to keep track if its the initial render and return something that doesn't rely on data from session storage if its the initial render – Twiggeh May 20 '20 at 11:34
  • https://stackoverflow.com/questions/59841800/react-useeffect-in-depth-use-of-useeffect/59841947#59841947 – Dennis Vash May 20 '20 at 11:34

2 Answers2

0

useEffect runs AFTER each render.

Hence setting data that the render relies upon in a useEffect before the render wont work.

The best solution I can come up with is to set state that keeps track if the component is being rendered for the first time, so that the initial return of the component doesn't rely on data that will be set by useEffect.

Twiggeh
  • 1,030
  • 1
  • 12
  • 24
0

I am not sure whether you are assuming that the useEffect is not running because you are getting a result is undefined error. However if that is the case then assigning a default value to the result const will be required as the useEffect is running after the first attempt to render.

So

const [result, setResult] = useState({})

This will always work whether you are navigating from somewhere or reloading. You are anyway setting the correct state in the useEffect.

https://codesandbox.io/s/busy-williams-j5spe?file=/src/Lobby.jsx

Mohit Mutha
  • 2,921
  • 14
  • 25