Reactjs 反应useState导致双重渲染
考虑规范的Reactjs 反应useState导致双重渲染,reactjs,react-hooks,Reactjs,React Hooks,考虑规范的useState示例: import React, { useState } from 'react'; const MyComponent = () => { const [count, setCount] = useState(0); console.log(count); return ( <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}
useState
示例:
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;
import React,{useState}来自“React”;
常量MyComponent=()=>{
const[count,setCount]=useState(0);
控制台日志(计数);
返回(
计数:{count}
setCount(计数+1)}>增量
);
};
导出默认MyComponent;
单击按钮使每个状态打印两次。为什么呢
将
控制台.log
放在一个没有依赖项的useffect
钩子中,您将看到它实际上不会呈现两次
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;
import React,{useffect,useState}来自“React”;
常量MyComponent=()=>{
const[count,setCount]=useState(0);
useffect(()=>{
控制台日志(计数);
});
返回(
计数:{count}
setCount(计数+1)}>增量
);
};
导出默认MyComponent;
这是一个很好的组件生命周期图,它列出了基于类的生命周期函数,但呈现/提交阶段是相同的
需要注意的重要一点是,组件可以“渲染”,而无需实际提交(即,您在屏幕上看到的常规渲染)。console.log本身就是其中的一部分。效果在“提交”阶段之后运行
。。。传递给useEffect的函数将运行
将渲染提交到屏幕后
默认情况下,效果在每次完成渲染后运行
反应严格模式
严格模式不能自动检测副作用,但它
通过使它们更具确定性,可以帮助您识别它们。
这是通过故意双重调用以下函数来实现的:
- 类组件
,构造函数
,以及呈现
方法应组件更新
- 类组件静态
方法getDerivedStateFromProps
- 功能组件主体
- 状态更新程序函数(设置状态的第一个参数)
- 传递给
、useState
或usemo
useReducer
这仅适用于开发模式。有关双重渲染的更多信息(根据已关闭的react问题) 这是StrictMode的一个故意特征。这只发生在开发中,有助于发现渲染阶段的意外副作用。我们只对带有挂钩的组件执行此操作,因为这些组件更可能在错误的位置意外产生副作用 另一个相关问题在这里 这样,渲染将一次执行2次
这样渲染将一次执行1次谢谢。根据该图,组件主体内部的日志记录是没有意义的,因为React可以随时重新启动“呈现阶段”,而
useffect
确保在“提交阶段”(实际DOM呈现)调用,所有日志记录都应该在那里完成。我这样说对吗?对。对于一些快速的脏日志记录(比如调试之类的),在功能体中删除日志实际上不会造成任何伤害。
const countRef = useRef(1);
countRef.current += 1;
const countRef = useRef(1);
useEffect(() => {
countRef.current += 1;
})