Home > Back-end >  What is the effect if a useEffect listens to a non-state value, of having a non-state value in the d
What is the effect if a useEffect listens to a non-state value, of having a non-state value in the d

Time:06-06

Each time Comp re-renders, rand will be a different value. Will it trigger the useEffect?

function Comp({}) {
  const rand = Math.random();

  useEffect(() => {
    // do stuff
  }, [rand])
}

CodePudding user response:

The variable in the dependencies's array is not tied to the fact it's a state set with some setState. As long as it's in the array and it changes, useEffect's callback gets called again. Now, how useEffect notices that change? Well it does a diff whenever the component render. And only a state set with a setState can re-render a component.

I made up an example to explain more. If you already understood the mechanisme, you could stop here, and go build your amazing product with React :). Otherwise, keep reading.

Say we have this component:

export default function Comp() {
  let rand = Math.random();
  useEffect(() => {
    console.log("Hello Word");
  }, [rand]);
  return (
      <button onClick={() => { rand = Math.random() }}>
        New value
      </button>
  );
}

We should have Hello Word logged in the console when the component render first time, and every time rand changes. Clicking on that button changes rand, but we won't have a new, log, because there isn't any re-render as no state has changed. And since there isn't a re-render, useEffect is not aware of the change.

Now let's take this same component, and change it a little bit:

export default function Comp() {
  const [state, setState] = useState(true); // new line added
  let rand = Math.random();
  useEffect(() => {
    console.log("Hello Word");
  }, [rand]);
  // notice that the click handler has changed
  return (
      <button onClick={() => setState(!state)}>
        New value
      </button>
  );
}

Now every time you click on the button the component re-render, because we are setting a state with setState, and while re-rendering if the value of rand changes from the previous one, we will get a new log.

But since we are using Math.random() we could have two similar values in rand for two renders, in which case there wouldn't be a new log.

CodePudding user response:

Every time that the component will be re-render the Math.random method will be evaluated, so it will cause the useEffect to run again (with the exception that rand has changed).

Instead, if it will be just a constant, it not re-run the useEffect.

CodePudding user response:

if you console.log("hello") inside the useEffect, you'll see that you only see two console's showing "hello"(because of componentWillMount and componentDidMount). This means that, your component will only re-render if a value of a state variable has changed or props that is been passed to this is changed (offcourse the props passed have to be a state or else it won't rerender).

Conclusion : Only change in value of state or props in a component re-renders the component.

  • Related