skip to Main Content

I have the following code:

function App() {

 const [appData, setAppData] = useState(initialAppDataValue);
const [test, setTest] = useState("");

// outside useEffect
if(!DataProviderService.isInitialized){
    fetchData();
}

// inside useEffect
/*useEffect(() => {
    fetchData();
}, []);*/

function fetchData(){
    DataProviderService.getAppData().then((data) => {
        setAppData(data);
        setTest("abc");
    });
}

return (<div>something...</div>);
}

If I call ‘fetchData’ outside useEffect the update of the state is not working BUT if I do it inside useEffect it works fine.

My question is why?
Outside of useEffect I update the state and then I see that re-render is called but the value doesn’t contain the new value. I don’t understand why.

2

Answers


  1. In this code, fetchData is called when component is rendering.
    When first rendering, DataProviderService is not initialized and fetchData is not called.
    After that, no states or props are changed, and the component is not re-rendered again and fetchData is not called.

    Login or Signup to reply.
  2. *When you call fetchData outside the useEffect, it runs immediately when the component is rendered. The DataProviderService.getAppData().then(…) part is asynchronous which means that it doesn’t wait for the result before moving on to the next lines of code and starts the process but doesn’t wait. setAppData and setTest are functions that update the component’s state. When the state is updated, it triggers a re-render of the component. As we know the promise is asynchronous, the state updates might not have been completed by the time the re-render occurs. This can lead to a situation where the component re-renders with the old state values.

    When you put fetchData inside the useEffect with an empty [], it ensures that fetchData is only executed once when the component is first displayed.The DataProviderService.getAppData().then(…) part is doing some work, and it takes time to finish. But now, because fetchData is inside useEffect, it doesn’t run immediately when the component renders.The useEffect captures the first time the component is shown on the screen. It waits for the asynchronous work (DataProviderService.getAppData().then(…)) to complete before moving on.After the asynchronous work is done, the state is updated using setAppData and setTest. This triggers a re-render, but now the re-render happens after the asynchronous task is finished. So, when the component re-renders, it shows the updated and correct information.*

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search