Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks render twice

I define a scene: we have a component that uses parent's props and itself state.

There are two Components DC and JOKER and my step under the below:

  1. click DC's button
  2. DC setCount
  3. JOKER will render with the old state
  4. running useEffect and setCount
  5. JOKER does render again

enter image description here

I want to ask why JOKER render twice(step 3 and 5) and the first render squanders the performance. I just do not want step 3. If in class component I can use componentShouldUpdate to avoid it. But Hooks has the same something?

My code under the below, or open this website https://jsfiddle.net/stephenkingsley/sw5qnjg7/

import React, { PureComponent, useState, useEffect, } from 'react';

function JOKER(props) {
  const [count, setCount] = useState(props.count);
  useEffect(() => {
    console.log('I am JOKER\'s useEffect--->', props.count);
    setCount(props.count);
  }, [props.count]);

  console.log('I am JOKER\'s  render-->', count);
  return (
    <div>
      <p style={{ color: 'red' }}>JOKER: You clicked {count} times</p>
    </div>
  );
}

function DC() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => {
        console.log('\n');
        setCount(count + 1);
      }}>
        Click me
      </button>
      <JOKER count={count} />
    </div>
  );
}

ReactDOM.render(<DC />, document.querySelector("#app"))
like image 547
Stephen Kingsley Avatar asked Oct 29 '19 07:10

Stephen Kingsley


People also ask

Why is useEffect rendering two times?

The standard behavior of the useEffect hook was modified when React 18 was introduced in March of 2022. If your application is acting weird after you updated to React 18, this is simply due to the fact that the original behavior of the useEffect hook was changed to execute the effect twice instead of once.

Why is my React app rendering twice?

The reason why this happens is an intentional feature of the React. StrictMode . It only happens in development mode and should help to find accidental side effects in the render phase.

How do I stop multiple rendering in React hooks?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

Why does React 18 render twice?

If you have the StrictMode enabled, it will fire two times the useEffect on development mode to make sure that you are aware of the possible side-effects that could appear.


2 Answers

It's an intentional feature of the StrictMode. This only happens in development, and helps find accidental side effects put into the render phase. We only do this for components with Hooks because those are more likely to accidentally have side effects in the wrong place. -- gaearon commented on Mar 9, 2019

like image 78
Vijay Sharma Avatar answered Nov 15 '22 17:11

Vijay Sharma


I'm not sure I understand your question, but here goes.

When your <DC /> component changes state, it passes the new state value count to the component Joker. At this point the component will rerender, accounting for the first change.

Then you bind the effect to props.count changes;

  useEffect(() => {
    console.log('I am JOKER\'s useEffect--->', props.count);
    setCount(props.count); 
  }, [props.count]);// <-- This one

Which triggers when the component gets the new value from the component DC. It will set the state of it self Joker to props.count, which causes the component to rerender.

Which then gives you the following output:

I am JOKER's  render--> 1 // Initial render where Joker receives props from DC
index.js:27 I am JOKER's useEffect---> 2 // The hook runs because props.count changed
index.js:27 I am JOKER's  render--> 2 // Joker rerenders because its state updated.
like image 32
Dennis Avatar answered Nov 15 '22 17:11

Dennis