将props发送到PureComponent
或功能组件时,可以使用不会为每个渲染更改的props来优化性能,这将阻止组件重新渲染。
使用类组件时这很简单:
class Component extends React.Component {
render() {
return <List createRows={this.createRows}/>;
}
createRows = () => this.props.data.map(dataToRow);
}
鉴于List
是PureCompoment
或功能组件,createRows
道具将永远不会导致重新渲染List
。
但如果Component
是一个功能组件,则不再可能:
function Component(props) {
return <List createRows={createRows}/>;
function createRows() {
return props.data.map(dataToRow);
}
}
由于每次createRows
渲染时都会创建Component
,所以道具会发生变化,每次重新渲染List
时都会重新渲染Component
。这可能会导致性能大幅下降。另请注意,createRows
不能放在功能组件之外,因为它取决于data
的List
道具。
现在,随着Hooks的介绍,可以将createRows
保存在useState
钩子中:
function Component(props) {
const [ createRows ] = useState(() => () =>
props.data.map(dataToRow);
);
return <List createRows={createRows}/>;
}
由于createRows
保存在状态钩子中,因此每次渲染都不会改变,并且不会像我们想要的那样重新渲染List
。
然而,这似乎更像是一个黑客而不是一个解决方案。
将函数prop从函数组件发送到子组件的最佳做法是什么,而不会导致对子组件进行不必要的重新渲染?
useCallback
钩子正好解决了这个问题。我建议你仔细阅读官方guide to hooks,它几乎回答所有可能的问题
function Component(props) {
const createRows = useCallback(() =>
props.data.map(dataToRow);
), []); // provide dependencies here
return <List createRows={createRows}/>;
}