Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应useState导致双重渲染_Reactjs_React Hooks - Fatal编程技术网

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;
})