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

dar*_*urf 9 javascript reactjs react-hooks

当向一个PureComponent或功能组件发送 props 时,你可以通过使用不会在每次渲染时改变的 props 来优化性能,这将阻止组件重新渲染。

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

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

  createRows = () => this.props.data.map(dataToRow);
}
Run Code Online (Sandbox Code Playgroud)

鉴于List是一个PureCompoment或功能组件,createRows道具永远不会导致重新渲染List.


但是如果Component是一个功能组件,这将不再可能:

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

    function createRows() {
      return props.data.map(dataToRow);
    }
  }
Run Code Online (Sandbox Code Playgroud)

由于createRows每次Component渲染时都会创建,因此道具会发生变化,导致List每次重新渲染时都会Component重新渲染。这会导致性能的巨大损失。还要注意createRows不能放置在功能组件之外,因为它依赖于 的data道具List


现在,随着 Hooks 的介绍,可以将 保持createRows在一个useState钩子中:

  function Component(props) {
    const [ createRows ] = useState(() => () =>
      props.data.map(dataToRow);
    );

    return <List createRows={createRows}/>;
  }
Run Code Online (Sandbox Code Playgroud)

由于createRows保存在状态钩子中,它不会随着每次渲染而改变,也不会List像我们想要的那样重新渲染。

然而,这似乎更像是一个黑客而不是解决方案。


将函数道具从功能组件发送到子组件而不导致子组件不必要的重新渲染的最佳实践是什么?

GPr*_*ost 12

useCallbackhook 的存在正是为了解决这个问题。我建议你仔细阅读官方的hooks 指南,它几乎回答了所有可能的问题

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

    return <List createRows={createRows}/>;
  }
Run Code Online (Sandbox Code Playgroud)