微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

当我将 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 的行为。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。