小编典典

React 16.3中从props更新canvas的正确生命周期方法是什么?

reactjs

我有一个Canvas组件,它看起来像这样:

class Canvas extends React.Component{



    saveRef = node => {

        this._canvas = node;

    }



    shouldComponentUpdate(){

        /*I will never re-render this component*/

        return false;

    }



    componentWillReceiveProps( nextProps ){

        /*Here I do manipulations with this._ctx, when new props come*/

    }



    render(){

        return (

            <canvas ref={this.saveRef} />

        );

    }



    componentDidMount(){

        this._ctx = this._canvas.getContext( "2d" );

    }

}


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

React社区开始弃用componentWillReceiveProps以替换它getDerivedStateFromProps。我可以componentDidUpdate用来执行我的绘图,但是随后我需要删除它,shouldComponentUpdate并且会有很多无用的渲染调用。有新的道具出现时,在React
16.3中更新我的组件的正确性能方法是什么?


阅读 680

收藏
2020-07-22

共1个答案

小编典典

使用componentDidUpdate的DOM操作是这样的。shouldComponentUpdate对于只有一个始终具有相同道具的单个孩子的组件,A
并不会真正起作用。因此,您应该能够删除它,而性能没有明显差异。

如果您已经分析了应用程序 并确定在这种特殊情况下 确实 有所作为,则可以将元素提升到构造函数中。

这样,React会完全跳过它(有效的工作方式与相同shouldComponentUpdate):

class Canvas extends React.Component {
  constructor(props) {
    super(props);
    this._ctx = null;
    this._child = <canvas ref={node => {
      this._ctx = node ? node.getContext('2d') : null
    } />;
  }

  componentDidUpdate(prevProps){
    // Manipulate this._ctx here
  }

  render() {
    // A constant element tells React to never re-render
    return this._child;
  }
}

您还可以将其分为两个部分:

class Canvas extends React.Component {
  saveContext = ctx => {
    this._ctx = ctx;
  }

  componentDidUpdate(prevProps){
    // Manipulate this._ctx here
  }

  render() {
    return <PureCanvas contextRef={this.saveContext} />;
  }
}


class PureCanvas extends React.Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    return (
      <canvas
        ref={node => node ? this.props.contextRef(node.getContext('2d') : null)}
      />;
  }
}
2020-07-22