【发布时间】:2020-07-12 07:21:08
【问题描述】:
我的代码有一个组件,它接受两个 props 并有自己的内部状态。
组件应仅在其道具更改时重新渲染。状态更改不应触发重新渲染。
此行为可以通过基于类的组件和自定义 shouldComponentUpdate 函数来实现。
但是,这将是代码库中第一个基于类的组件。一切都是通过功能组件和钩子完成的。
因此,我想知道是否可以使用功能组件编写所需的功能。
在几个没有解决真正问题的答案之后,我想我必须重新提出我的问题。这是一个包含两个组件的最小示例:
- Inner 接受一个 prop 并具有状态。这是有问题的组件。状态更改后不得重新渲染。道具更改应触发重新渲染。
- 外部是内部的包装。它在这个问题的范围内没有任何意义,只是为了给 Inner 提供道具并模拟道具更改。
为了演示所需的功能,我使用基于类的组件实现了 Inner。 A live version of this code can be found on codesandbox。如何将其迁移到功能组件:
Inner.tsx:
import React, { Component } from 'react'
interface InnerProps{outerNum:number}
interface InnerState{innerNum:number}
export default class Inner extends Component<InnerProps, InnerState> {
state = {innerNum:0};
shouldComponentUpdate(nextProps:InnerProps, nextState:InnerState){
return this.props != nextProps;
}
render() {
return (
<button onClick={()=>{
this.setState({innerNum: Math.floor(Math.random()*10)})
}}>
{`${this.props.outerNum}, ${this.state.innerNum}`}
</button>
)
}
}
外部.tsx:
import React, { useState } from "react";
import Inner from "./Inner";
export default function Outer() {
const [outerState, setOuterState] = useState(1);
return (
<>
<button
onClick={() => {
setOuterState(Math.floor(Math.random() * 10));
}}
>
change outer state
</button>
<Inner outerNum={outerState}></Inner>
</>
);
}
The official docs say 将组件包装在React.memo 中。但这似乎不适用于防止状态更改的重新渲染。它仅适用于道具更改。
我试图让React.memo 工作。你可以看到一个代码版本,其中 Outer 和 Inner 都是功能组件here。
相关问题:
How to use shouldComponentUpdate with React Hooks? :这个问题只涉及道具更改。接受的答案建议使用React.memo
shouldComponentUpdate in function components:这个问题早于有状态的功能组件。接受的答案解释了功能组件如何不需要shouldComponentUpdate,因为它们是无状态的。
【问题讨论】:
-
React.memo:“这个方法只作为性能优化存在。不要依赖它来“阻止”渲染,因为这会导致错误。” - 你能向我们介绍你可能需要它的情况吗?也许我们可以建议其他解决方案,例如引入
key属性。但如果没有案例本身,就很难推断出问题所在。
标签: javascript reactjs react-hooks reactive-programming