我在stackoverflow上发现了类似的问题,但没有一个使我解决。
我正在使用带有功能组件的react 16.12.0。 我有这个应用程序:
const App: React.FC<Props> = (props) => {
const [value1, setValue1] = useState<number>(1);
const [value2, setValue2] = useState<boolean>(true);
function incrementValue1(){
setValue1(value1+1);
}
function sendToServer(){
...do something...
}
return (
<>
<Row>
<Col>
<Child value2={value2} sendToServer={sendToServer} />
</Col>
</Row>
<Row>
<Col>
<Button variant="outlined"
color="primary"
size="large"
onClick={incrementValue1}>
Increment value1
</Button>
</Col>
</Row>
</>
);
};
export default App;
尽管父级正在更改一个值,这与子级组件无关,但是每次父级组件渲染时,子级组件都会重新渲染。
我了解了备忘录,可以将任何组件合并到备忘录中,并使用备忘录的第二个参数告诉何时渲染。但我不确定是否正确。在重写很多类之前,我想知道哪种方法是正确的。 例如:
const Child: React.FC<Props> = React.memo(props) => {
...Logic from child component...
},[props.value2])
正确的做法是什么?
答案 0 :(得分:1)
如果您的功能组件使用相同的道具呈现相同的结果,则可以将其包装在对React.memo的调用中,以在某些情况下通过记忆结果来提高性能
因此,基本上,如果将Child
组件包装到React.memo
中,则在道具不随时间变化的情况下,该组件将不会重新渲染
// Child component
function Child({value2, sendToServer}) {
...
}
export default React.memo(Child);
如果您只想在属性Child
发生变化时重新渲染value2
组件,仅 ,则可以使用第二个参数,该参数应返回true
不需要重新呈现组件时
它将是:
export default React.memo(
Child,
(prevProps, nextProps) => prevProps.value2 === nextProps.value2
);
答案 1 :(得分:1)
您可以只使用普通的React.memo:
const Child = React.memo((props) => {
...
});
这样,如果孩子的所有道具都相等,孩子将跳过重新渲染。
您需要做的另一项更改是将sendToServer
用React.useCallback包裹
const sendToServer = React.useCallback(function() {
...
}, []);
useCallback将对sendToServer
的引用与整个渲染器相同,因此该Child的记忆将起作用。这就是useCallback
存在的确切用例。
答案 2 :(得分:1)
您应该理解,用memo
包装所有组件也将花费一些资源。因此,我建议您不要在乎重新渲染组件,只要这个重新渲染不会影响任何“昂贵”的计算,这不是一个大问题。
对于那些(昂贵的)代码部分,我建议您使用useMemo。因此,仅在实际需要的地方使用该优化。