Comments (6)
Unless I'm missing something, you are getting the first console.log
on the initial render of the component. After clicking the button you are mutating the state of a
which is a dependency of an effect that, in turn, mutates the state of b
. These mutations individually cause re-renders, which is why you see "render 2" logged twice.
from react.
Unless I'm missing something, you are getting the first
console.log
on the initial render of the component. After clicking the button you are mutating the state ofa
which is a dependency of an effect that, in turn, mutates the state ofb
. These mutations individually cause re-renders, which is why you see "render 2" logged twice.
Changing the state of a will trigger the side effect function to execute setB(b), but this will not change the state of b, because the state after the change is the same as the state before the change.So it should not cause re-renders.
from react.
Unless I'm missing something, you are getting the first
console.log
on the initial render of the component. After clicking the button you are mutating the state ofa
which is a dependency of an effect that, in turn, mutates the state ofb
. These mutations individually cause re-renders, which is why you see "render 2" logged twice.Changing the state of a will trigger the side effect function to execute setB(b), but this will not change the state of b, because the state after the change is the same as the state before the change.So it should not cause re-renders.
Even if the value of b
remains the same after calling setB(b)
, React still considers it as a state update and triggers a re-render of the component. I might be wrong here, but I believe React internally batches state updates and performs them asynchronously for performance reasons. So even though the value of b
doesn't change, React still queues a re-render for the component.
from react.
from react.
Firstly, I think the conclusion you have drawn from debugging is problematic, and I hope you can confirm it again.
Secondly, the setB (b)
method does not trigger an update, only setA (a+1)
will trigger this update. The reason why "render, a, b" is printed twice is that React hooks re-executes function components when setState is called, hence there are two console.log. However, this does not mean that it has been updated twice. We know that React updates and renders the contents in render
(corresponding to the return
in function components). If you add a Math.random()
content in the return
, you will find that in fact, setB (b) does not trigger the second update, only setA (a+1) will trigger the update. But in your example, it is not easy to observe this situation. I have made modifications to your example, and the principle is consistent. Here is the codesandbox link: https://codesandbox.io/s/update-issues-about-react-hooks-8dvqyk?file=/src/App.js
However, later on, I found that in the example in the codesandbox link, clicking the clickB button will only trigger console.log
once, and it will not trigger again no matter how many times it is clicked. However, every time I click the clickA button and then click the clickB button, console.log can be triggered again. This also shows that after React is re-rendered due to setA(a + 1), even if a setState is executed with a value that has not changed (i.e. setB(b)) and this will not cause an update, it allows the function component to be re-executed once. Then if it is found that nothing has changed, it will not trigger again. This is my guess, and I have not found a reasonable explanation for it yet, but as long as setB(b) does not trigger extra redundant rendering, there is no problem with performance waste.
Regarding the other question, you found that lane === 1
during debugging because the current mode is Legacy mode, and the priority of all update objects is syncLane, which is binary 0000...0001, corresponding to decimal 1. This update object was generated when the setA(a + 1) method was called by clicking the button.
The above is my personal understanding, I hope itβs helpful to you. If there are any errors, criticisms and corrections are welcome.
from react.
Firstly, I think the conclusion you have drawn from debugging is problematic, and I hope you can confirm it again.
Secondly, the
setB (b)
method does not trigger an update, onlysetA (a+1)
will trigger this update. The reason why "render, a, b" is printed twice is that React hooks re-executes function components when setState is called, hence there are two console.log. However, this does not mean that it has been updated twice. We know that React updates and renders the contents inrender
(corresponding to thereturn
in function components). If you add aMath.random()
content in thereturn
, you will find that in fact, setB (b) does not trigger the second update, only setA (a+1) will trigger the update. But in your example, it is not easy to observe this situation. I have made modifications to your example, and the principle is consistent. Here is the codesandbox link: https://codesandbox.io/s/update-issues-about-react-hooks-8dvqyk?file=/src/App.jsHowever, later on, I found that in the example in the codesandbox link, clicking the clickB button will only trigger
console.log
once, and it will not trigger again no matter how many times it is clicked. However, every time I click the clickA button and then click the clickB button, console.log can be triggered again. This also shows that after React is re-rendered due to setA(a + 1), even if a setState is executed with a value that has not changed (i.e. setB(b)) and this will not cause an update, it allows the function component to be re-executed once. Then if it is found that nothing has changed, it will not trigger again. This is my guess, and I have not found a reasonable explanation for it yet, but as long as setB(b) does not trigger extra redundant rendering, there is no problem with performance waste.Regarding the other question, you found that
lane === 1
during debugging because the current mode is Legacy mode, and the priority of all update objects is syncLane, which is binary 0000...0001, corresponding to decimal 1. This update object was generated when the setA(a + 1) method was called by clicking the button.The above is my personal understanding, I hope itβs helpful to you. If there are any errors, criticisms and corrections are welcome.
This is very helpful for me, thanks
from react.
Related Issues (20)
- Bug: performance.mark is not a function HOT 3
- #usahomesforrent HOT 1
- Bug: Multiple React.Suspense breaks if all not wrapped in <Suspense> HOT 3
- [React 16] Bug: true and false clauses being rendered simultaneously HOT 6
- Bug: [18.3.0-canary] renderToString hoists some tags to top(working in 18.2) HOT 1
- Feature: Allow creating elements using document.createElement before rendering HOT 4
- Bug: For React/Server the renderToString with Suspense in the tree is not behaving as per what documentation says. HOT 5
- Bug: `eslint-plugin-react-hooks` doesn't work inside `export default () => { ... }` HOT 2
- [DevTools Bug] Cannot add node "1" because a node with that id is already in the Store. HOT 12
- [DevTools Bug] Node "24" was removed before its children. HOT 2
- [DevTools Bug]: Devtool extension build failing in windows and ubuntu HOT 10
- Bug: Devtools extension not building in windows and ubuntu HOT 2
- Bug: fixtures/packaging/babel-standalone/dev.html Gives 'ReactDOM.render is no longer supported' Error HOT 1
- Bug: `react-server-dom-esm` package is empty HOT 3
- Bug:
- Bug: `ReactDOM.preload()`
- Bug: react inspector "inspection" button doesn't work HOT 5
- Bug: d.split("+").at is not a function. (In 'd.split("+").at(-1)', 'd.split("+").at' is undefined) error in safari 14.1 running react js HOT 7
- [DevTools Bug]: react-hooks/rules-of-hooks does not report error for function starting with _ HOT 2
- Bug: React trigger multiple re-render by once setState (not use StrictMode) HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react.