React 16.3中用于从道具更新画布的正确生命周期方法是什么?

Ale*_*min 14 javascript lifecycle 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" );
    }
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

React社区开始弃用componentWillReceiveProps以替换它getDerivedStateFromProps.我可以componentDidUpdate用来执行我的绘图,但后来我需要删除shouldComponentUpdate,我将有很多无用的渲染调用.当新的道具来临时,在反应16.3中更新我的组件的正确高效方法是什么?

Dan*_*mov 17

使用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;
  }
}
Run Code Online (Sandbox Code Playgroud)

您还可以将其拆分为两个组件:

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)}
      />;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!它完全解决了我的问题! (2认同)