React useState 导致双重渲染 [英] React useState cause double rendering
问题描述
考虑规范的 useState
示例:
import React, { useState } from 'react';const MyComponent = () =>{const [count, setCount] = useState(0);控制台日志(计数);返回 (<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>计数:{计数}<button onClick={() =>setCount(count + 1)}>Increment
);};导出默认的 MyComponent;
点击按钮使每个状态打印两次.这是为什么?
将 console.log
放在一个 useEffect
钩子中,没有依赖关系,你会看到它不是't 实际上渲染了两次.
import React, { useEffect, useState } from 'react';const MyComponent = () =>{const [count, setCount] = useState(0);useEffect(() => {控制台日志(计数);});返回 (<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>计数:{计数}<button onClick={() =>setCount(count + 1)}>Increment
);};导出默认的 MyComponent;
这是一个很好的组件生命周期图,它列出了基于类的生命周期函数,但渲染/提交阶段是相同的.
需要注意的重要一点是组件可以被渲染"没有实际提交(即您在屏幕上看到的传统渲染).console.log 本身就是其中的一部分.效果在提交"中之后运行.阶段.
<块引用>... 传递给 useEffect 的函数会运行在渲染提交到屏幕之后....
默认情况下,效果在每次完成渲染后运行,...
反应严格模式
检测意外的副作用><块引用>
严格模式无法自动为您检测副作用,但它可以可以通过使它们更具确定性来帮助您发现它们.这是通过有意重复调用以下函数来实现的:
- 类组件
constructor
、render
和shouldComponentUpdate
方法 - 类组件静态
getDerivedStateFromProps
方法 - 函数组件主体
- 状态更新器函数(
setState
的第一个参数) - 传递给
useState
、useMemo
或useReducer
的函数
这只适用于开发模式.
Consider the canonical useState
example:
import React, { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
console.log(count);
return (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
count: {count}
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
Clicking the button makes each state print twice. Why is that?
Put the console.log
in an useEffect
hook without dependencies and you'll see it isn't actually rendering twice.
import React, { useEffect, useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(count);
});
return (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
count: {count}
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
Here's a good diagram of the component lifecycle, it lists the class-based lifecycle functions, but the render/commit phases are the same.
The import thing to note is that the component can be "rendered" without actually being committed (i.e. the conventional render you see to the screen). The console.log alone is part of that. The effects run after in the "commit" phase.
... The function passed to useEffect will run after the render is committed to the screen. ...
By default, effects run after every completed render, ...
React Strict Mode
Detecting Unexpected Side-effects
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Class component
constructor
,render
, andshouldComponentUpdate
methods- Class component static
getDerivedStateFromProps
method- Function component bodies
- State updater functions (the first argument to
setState
)- Functions passed to
useState
,useMemo
, oruseReducer
This only applies to development mode.
这篇关于React useState 导致双重渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!