【问题标题】:Do react functional and class components render differently?反应功能和类组件是否呈现不同?
【发布时间】:2023-03-29 18:10:02
【问题描述】:

当我使用带有状态管理器的反应功能组件(我正在使用recoil.js)并尝试使用反应挂钩更新状态时,它仅在状态不同时调用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, setTest] = useRecoilState(testAtom);
    
    useEffect(() => {
        console.log('effected', 'c2');
    });
    
    return (
        <div>
            <button onClick={() => {setTest('c2')}}>Click me</button>
        </div>
    );

}

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

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

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

【问题讨论】:

  • 没有。一个反应组件是一个反应组件。当状态和/或道具更新时,它们会重新渲染。基于类的组件的渲染方法类似于功能组件的整个主体。每次渲染都会调用 React 钩子,按照它们声明的顺序。
  • 你实际上可以制作一个类组件并检查你自己 - 它们以相同的方式呈现

标签: javascript reactjs recoiljs


【解决方案1】:

是和不是。我不会说“它们的渲染方式不同”,但是在确定 when 渲染组件的方式之间存在差异。我理解人们如何期望默认行为是相同的,但是,我也理解引入新的状态系统 (useState) 为开发人员提供了改进默认行为的机会。

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

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

所以这证实了你的观察。

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

现在正在寻找添加class 组件,来自setState documentation

setState() 总是会导致重新渲染,除非shouldComponentUpdate() 返回false

关于shouldComponentUpdate

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

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

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

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

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 2023-01-31
    • 2021-03-13
    • 2021-11-04
    • 2021-02-27
    • 2017-05-12
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    相关资源
    最近更新 更多