18

I have a react functional component and I want to run some code in every render . You know useEffect hook without dependency array runs every time on render.

heres the code

function Component({a, b}){

useEffect(()=>{
  console.log('component rerenderd')
  // some code here
})

 return(
  <div>
    Some content
  </div>
  )
}

on the other hand without useEffect doing same thing

function Component2({a, b}){

  console.log('component rerenderd')
  // some code here

 return(
  <div>
    Some content
  </div>
  )
}

My question is what is the difference between both of them ?

user13103887
  • 169
  • 1
  • 7
  • 2
    Does this answer your question? [React useEffect in depth / use of useEffect?](https://stackoverflow.com/questions/59841800/react-useeffect-in-depth-use-of-useeffect) – Dennis Vash Jun 30 '20 at 09:00

4 Answers4

9

useEffect callbacks executed after the render phase which is the main difference between the two.

See the next example:

// Log order:
// "executed at render phase"
// "executed after render phase"

const App = () => {
  useEffect(() => {
    console.log("executed after render phase");
  });

  console.log("executed at render phase");

  return <></>;
};

Edit useEffect execute phase

Read more here

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
3

In the second case, you're logging before returning the JSX. When you're using the first snippet the code inside the callback passed to useEffect runs after the component renders.

There are multiple other uses for using useEffect like doing something when the state changes etc.

Ramesh Reddy
  • 10,159
  • 3
  • 17
  • 32
2

useEffect can take 2 arguments, the first is a function and the second one is an array.

the function is being called as soon as the component gets mounted, but the extended feature that useEffect has is that it has a kind of sensivity list, which lets it run again in case of any argument in the second array changes. making it componentDidUpdate too.

but the console.log() without useEffect runs the way it runs. you don't have any control to it. this is a simple example:

useEffect(() => {
  console.log('count=', count);
}, [count]); // Only re-run the effect if count changes

It also has a cleanUp method, you can (for instance) write a time interval and it could be cleared when the component get unmounted. you can add a function named 'return' in the useEffect and it's done!

let timer;

useEffect(()=>{
  timer = setInterval(() => console.log('hello!'), 1000);
  return()=>clearImmediate(timer);
})

Now the interval gets cleared when the component gets unmounted.

Now if we pass something in the array to make useEffect listen to their change, the component will do the cleanUp method when useEffect runs again with the new value.

this is an example:

let timer;

useEffect(()=>{
  timer = setInterval(() => console.log('do you need something Mr./Mrs. ' + someOne + ' ?'), 1000);
  return()=>clearImmediate(timer);
},[someOne]);

We made a timer which asks someOne if he/she needs something every second. Now if the 'someOne' changes, it stops asking the previous one and starts to ask the new 'someOne' every second.

by the way, you can name the function 'return' anything you want, or you can just pass an arrow function.

Amir Gorji
  • 2,809
  • 1
  • 21
  • 26
  • 1
    Not exactly useEffect takes 2 argument it also accept [one argument](https://reactjs.org/docs/hooks-effect.html#example-using-hooks) , I know what 2nd argument does, my question wasnt about this – user13103887 Jun 30 '20 at 09:35
  • exactly, I forgot to write that. thanks for your note. – Amir Gorji Jun 30 '20 at 09:51
1

enter image description here

Functional components' entire function body is basically the "render" function, so anything there is called each time the component is rendered, which occurs during the "Render phase" which can be paused, aborted, or restarted by React when it is computing a diff.

The useEffect hook's callback is guaranteed to be called only once per render cycle, i.e. it is more akin to the componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle functions. Take note that these occur in the "Commit phase", meaning the DOM had been diffed and react is committing/flushing the UI changes to the DOM.

Try rendering your component with react's strict mode on and you'll definitely see a difference.

Detecting unexpected side effects

Drew Reese
  • 165,259
  • 14
  • 153
  • 181