React: Unexpected function component call using useState

Created on 20 Dec 2019  ·  3Comments  ·  Source: facebook/react

Do you want to request a feature or report a bug?

question

What is the current behavior?

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

import "./styles.css";

function Child() {
  console.log("Child render");
  return null;
}

function App() {
  const [count, setCount] = useState(0);

  console.log("Render");

  useEffect(() => {
    console.log("count changed", count);
  }, [count]);

  return (
    <div>
      <h2>UseState</h2>
      <p>clicked: {count}</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        +1
      </button>
      <button
        onClick={() => {
          setCount(count);
        }}
      >
        +0
      </button>
      <Child />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

There are two button in this count example. Clicking one makes count +1,another makes count no change. If clicking the no change button first, "Render" will not be logged. But if clicking the +1 button first and then clicking anthor,"Render" will show twice, but ""Child render" will only show once.

I found the explain in document.

If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)

Does React only promise that Children component will not be rendered in this situation? The current component may still be rendered?

This is an example in sandbox.

https://codesandbox.io/s/long-firefly-nz5px?fontsize=14&hidenavigation=1&theme=dark

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

"react": "^16.12.0",
"react-dom": "^16.12.0",

Question

Most helpful comment

This issue doesn't look like a "bug" so much as a question for clarification? :smile:

The next paragraph below the section of the docs you referenced says this:

Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree.

React bails out early when it knows it's safe to. In some cases, it needs to do a little more work to be sure that it's safe to bail out.

The reasons for why this is can't be explained without going fairly deep into the current implementation details- which probably wouldn't be that useful and they're likely to change in an upcoming release as we continue working on new APIs like concurrent mode and suspense.

The good news is, as the docs mention, the amount of additional work React does in either case should be small!

All 3 comments

This issue doesn't look like a "bug" so much as a question for clarification? :smile:

The next paragraph below the section of the docs you referenced says this:

Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree.

React bails out early when it knows it's safe to. In some cases, it needs to do a little more work to be sure that it's safe to bail out.

The reasons for why this is can't be explained without going fairly deep into the current implementation details- which probably wouldn't be that useful and they're likely to change in an upcoming release as we continue working on new APIs like concurrent mode and suspense.

The good news is, as the docs mention, the amount of additional work React does in either case should be small!

This issue doesn't look like a "bug" so much as a question for clarification? 😄

The next paragraph below the section of the docs you referenced says this:

Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree.

React bails out early when it knows it's safe to. In some cases, it needs to do a little more work to be sure that it's safe to bail out.

The reasons for why this is can't be explained without going fairly deep into the current implementation details- which probably wouldn't be that useful _and_ they're likely to change in an upcoming release as we continue working on new APIs like concurrent mode and suspense.

The good news is, as the docs mention, the amount of additional work React does in either case should be small!

Thx, what a careless man! 😁

No worries! 😄

Was this page helpful?
0 / 5 - 0 ratings