Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why useEffect doesn't call callback function if state doesn't change?

I have the following code(react 16.8.6, react-dom: 16.8.6):

import React, { useState, useEffect, } from 'react';
import ReactDOM from 'react-dom';

function App(props) {
   const [counter, setCounter] = useState(0);

   console.log(1)

   useEffect(() => {
    console.log(2)

     setTimeout(() => {
       console.log(3)

       setCounter(1);
     }, 10000)
   });

   return  counter;
 }

ReactDOM.render(<App />, document.getElementById('root'));

When App component is rendered first time, it prints:

1 2

After 10 seconds it prints:

3, 1, 2

Everything that was before is understandable for me, but now after 10 seconds it prints

3, 1

i.e. function that is passed to useEffect isn't called. I assume it's related to state somehow (as it doesn't change, if it changes useEffect works fine). Could you explain this behaviour?

like image 524
Roman Roman Avatar asked Aug 09 '26 13:08

Roman Roman


1 Answers

According to the docs

Does useEffect run after every render? Yes! By default, it runs both after the first render and after every update. (We will later talk about how to customize this.) Instead of thinking in terms of “mounting” and “updating”, you might find it easier to think that effects happen “after render”. React guarantees the DOM has been updated by the time it runs the effects.

An update never occurred after you call setCounter a second time, because 1 === 1 is always the same.

If you actually increment your counter by one every time you'll get your desired effect.

function App(props) {
   const [counter, setCounter] = useState(0);

   console.log(1)

   useEffect(() => {
    console.log(2)

     setTimeout(() => {
       console.log(3)

       setCounter(counter + 1);
     }, 10000)
   });

   return counter;
}

Live example

like image 150
kemicofa ghost Avatar answered Aug 11 '26 03:08

kemicofa ghost