反应功能和类组件的呈现方式是否不同?

问题描述

当我将 React 功能组件与某个状态管理器一起使用时(我正在使用 recoil.js)并尝试使用 React 钩子更新状态时,它仅在状态不同调用 useEffect比原来的状态。 当我迫不及待地讨论组件如何重新渲染的堆栈溢出时,他们在谈论类组件,以及每次调用 setState 时它们如何渲染。这只是两个组件类型工作方式之间的差异还是我误解了它?

这是我对功能组件的代码测试:

import React,{useEffect} from 'react'
import ReactDOM from 'react-dom'
import {atom,useRecoilState,RecoilRoot} from 'recoil'

ReactDOM.render(
    <React.StrictMode>
        <RecoilRoot>
            <App />
        </RecoilRoot>
    </React.StrictMode>,document.getElementById('root')
);

const testAtom = atom({
    key: "test",default: ""
});

function App(){
    return (
        <>
            <C1 />
            <C2 />
        </>
    );
}

function C1(){
    const [test,setTest] = useRecoilState(testAtom);
    
    useEffect(() => {
        console.log('effected','c1');
    });
    
    return (
        <div>
            <button onClick={() => {setTest('c1')}}>Click me</button>
        </div>
    );
}

function C2(){
    const [test,'c2');
    });
    
    return (
        <div>
            <button onClick={() => {setTest('c2')}}>Click me</button>
        </div>
    );

}

运行这个useEffect只在状态改变的时候调用,不仅仅是setTest被调用的时候,而是这个person said otherwise对于类组件。

React 不会比较状态数据。当 setState 被调用时,它会将组件标记为脏(这意味着它需要重新渲染)。

这是否意味着如果我将它作为一个类组件,它每次都会conoslelog?

解决方法

是和否。我不会说“它们以不同的方式呈现”,但是如何确定 何时 重新呈现组件是有区别的。我理解人们如何期望默认行为是相同的,但是,我也理解引入新的状态系统 (useState) 为开发人员提供了改进默认行为的机会。

我不知道后坐力是如何具体工作的,但我认为它的行为至少类似于 useState 重新渲染组件。来自documentation

如果您将 State Hook 更新为与当前状态相同的值,React 将退出而不渲染子项或触发效果。 (React 使用 Object.is comparison algorithm。)

所以这证实了你的观察。

但让我明确一点:这不是函数组件的特性,这正是 useState 的工作原理。您可以开发自己的状态管理钩子,它的行为有所不同。

现在从 setState documentation 添加 class 组件:

setState() 将始终导致重新渲染,除非 shouldComponentUpdate() 返回 false

关于shouldComponentUpdate

使用 shouldComponentUpdate() 让 React 知道组件的输出是否不受当前 state 或 props 变化的影响。默认行为是在每次状态更改时重新渲染,在绝大多数情况下,您应该依赖默认行为。

shouldComponentUpdate() 在接收新道具或状态时在渲染之前调用。默认为 true

第一部分不太清楚(“默认行为是在每次状态更改时重新渲染”,但是否将相同的值设置为“更改”?),但是第二部分段说清楚。 shouldComponentUpdate 默认返回 true,因此组件将始终在调用 setState 时重新渲染。

如果您实现 shouldComponentUpdate 来调用 Object.is,您将复制 useState 的行为。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...