我有一个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中更新我的组件的正确性能方法是什么?
componentWillReceiveProps
getDerivedStateFromProps
componentDidUpdate
shouldComponentUpdate
使用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)} />; } }