React useState 导致双重渲染

gal*_*h92 8 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' }}>
      count: {count}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default MyComponent;
Run Code Online (Sandbox Code Playgroud)

单击该按钮可使每个状态打印两次。这是为什么?

短屏幕

Dre*_*ese 13

把它console.log放在一个useEffect没有依赖关系的钩子里,你会看到它实际上并没有渲染两次。

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;
Run Code Online (Sandbox Code Playgroud)

编辑精彩特斯拉-cf8uu

这是一个很好的组件生命周期图,它列出了基于类的生命周期函数,但渲染/提交阶段是相同的。

在此处输入图片说明

需要注意的重要事项是组件可以在没有实际提交的情况下“渲染”(即您在屏幕上看到的常规渲染)。console.log 本身就是其中的一部分。效果运行后,在“提交”阶段。

使用效果

... 传递给 useEffect 的函数将在渲染提交到屏幕后运行。...

默认情况下,效果在每次完成渲染后运行,...

反应严格模式

检测意外的副作用

严格模式无法自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。这是通过有意重复调用以下函数来完成的:

  • 类成分 constructor rendershouldComponentUpdate方法
  • 类组件静态getDerivedStateFromProps方法
  • 函数组件体
  • 状态更新器函数(的第一个参数setState
  • 函数传递给useStateuseMemouseReducer

这仅适用于开发模式。