从功能组件发送功能道具时,防止重新渲染

时间:2019-04-01 14:37:13

标签: javascript reactjs react-hooks

将道具发送到PureComponent或功能组件时,可以通过使用不会针对每个渲染进行更改的道具来优化性能,这将阻止组件重新渲染。

使用类组件时,这很简单:

class Component extends React.Component {
  render() {
    return <List createRows={this.createRows}/>;
  }

  createRows = () => this.props.data.map(dataToRow);
}

鉴于ListPureCompoment或功能组件,createRows道具将永远不会导致List的重新呈现。


但是,如果Component是功能组件,则不再可能:

  function Component(props) {
    return <List createRows={createRows}/>;

    function createRows() {
      return props.data.map(dataToRow);
    }
  }

由于每次createRows都会创建Component,所以道具会发生变化,导致List每次重新渲染时都会重新渲染Component。这会导致性能上的巨大损失。还请注意,createRows不能放置在功能组件之外,因为它取决于data的{​​{1}}属性。


现在,随着Hooks的介绍,可以将List放在createRows钩子中:

useState

由于 function Component(props) { const [ createRows ] = useState(() => () => props.data.map(dataToRow); ); return <List createRows={createRows}/>; } 被保存在状态挂钩中,因此不会随每次渲染而改变,并且createRows的重新渲染都不会发生,就像我们想要的那样。

但是,这似乎更像是一种破解而不是解决方案。


在不导致子组件不必要的重新渲染的情况下,将功能道具从功能组件发送到子组件的最佳实践是什么?

2 个答案:

答案 0 :(得分:2)

useCallback钩子正好可以解决此问题。我建议您仔细阅读官方的guide to hooks,它几​​乎可以回答所有可能的问题

  function Component(props) {
    const createRows = useCallback(() =>
      props.data.map(dataToRow);
    ), []); // provide dependencies here

    return <List createRows={createRows}/>;
  }

答案 1 :(得分:1)