2

I know useEffect() with no array run the callback only at the first render.

Then what is the differences between useEffect(()=>{},[]) and no useEffect().

I mean between this:

function myComponent() {
  // some states, variables

  useEffect(() => {
    // do something on mount <= this is my current concern.
  }, [/* empty */]);

  // return Element ...
}

and this:

function myComponent() {
  // some states, variables

  // do something on mount <= this is my current concern.
  
  // return Element ...
}

5 Answers 5

7

In React, a component re-renders whenever there is a change in it's state or one of it's props.
The reason it behaves like this is so that it would be possible to "react" to a change in the mentioned data, and to reflect UI changes accordingly.

Every time the component re-renders, so does any logic within it that is not cached (functions, variables, etc..)

useEffect helps us with reacting to a change in the state or props that are stated in it's dependency array.
It gives us to option to automatically run a callback function in such an event/s.

useEffect with an empty dependency array, will run only a single time when the component is mounted.

So in this example -

function myComponent() {
  // some states, variables

  useEffect(() => {
    // do something on mount <= this is my current concern.
  }, [/* empty */]);

  // return Element ...
}

The callback function inside the useEffect will run only once, when the component is first "brought to life".
Subsequent renders will not invoke this.

While in this example -

function myComponent() {
  // some states, variables

  // do something on mount <= this is my current concern.
  
  // return Element ...
}

Whatever you put in there will run every time the component re-renders.
Whether this is ok or not depends on your use-case and what function are you trying to run, if it's "cheap" to run or not, etc..

Sign up to request clarification or add additional context in comments.

4 Comments

There is an error in your statement that "In React, a component re-renders whenever there is a change in it's state or one of it's props." This is not true. According to this, In normal rendering, React does not care whether "props changed" - it will render child components unconditionally just because the parent rendered
True, though we can prevent that from happening with memoization, etc.. The bottom line is, however, that if a prop changes, the component does indeed re-render, so how is that not true? i.e. - in effect, the component still re-renders...
Good point, the statement is not "false", just misleading. Components re-render when props change, but also when a parent is rendered (which will happen even if a component has 0 props)
You are right. I think it's also safe to explain it like I did, because it's easier to understand and remember for beginners IMO. But you definitely said it more accurately.
2
function myComponent() {
   useEffect(() => {
   }, []);

}

here useEffect(()=>{},[]) works like componentDidMount

and

function myComponent() {
}

this is normal js function

Comments

1

They will be executed every time at component re-render if you put them in function directly

Comments

1

As you mentioned, when you have an empty dependency (like below), the code inside will only run on mount.

  useEffect(() => {
    something() // only runs on mount
  }, []);

If you don't have a useEffect at all, the code will be run every time the component rerenders.

function myComponent() {
  // some states, variables

  something() // runs on every rerender
  
  // return ...
}

Now the question is, "when does a rerender happen?". In general, anytime a parent component renders, React will rerender all children of that component. So rerenders can occur quite often.

Look at this article, which has some really helpful visual examples of when components rerender.

Comments

1

if the dependency array is empty you will only run the useEffect on mount. While not using useEffect, the code inside your component will run every time you rerender the page/component.

function myComponent(){
   console.log('render') // will run everytime you render
   return ()
}


function myComponent(){
  useEffect(() => {
    console.log('on mount'); // run on mount
  }, [])
  return ()
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.