React useState 导致双重渲染 [英] React useState cause double rendering

查看:287
本文介绍了React useState 导致双重渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑规范的 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

<块引用>

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

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

反应严格模式

检测意外的副作用<块引用>

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

  • 类组件constructorrendershouldComponentUpdate方法
  • 类组件静态getDerivedStateFromProps方法
  • 函数组件主体
  • 状态更新器函数(setState 的第一个参数)
  • 传递给 useStateuseMemouseReducer
  • 的函数

这只适用于开发模式.

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.

useEffect

... 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, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer

This only applies to development mode.

这篇关于React useState 导致双重渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆