J'ai un composant Canvas, qui ressemble à peu près à ceci:
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>
La communauté de réaction a commencé à déprécier componentWillReceiveProps
afin de le remplacer par getDerivedStateFromProps
. Je peux utiliser componentDidUpdate
pour réaliser mes dessins, mais je dois ensuite supprimer shouldComponentUpdate
et j'aurai beaucoup d'appels de rendu inutiles. Quelle est la méthode la plus performante pour mettre à jour mon composant dans la réaction 16.3, lorsque de nouveaux accessoires arrivent?
Utilisez componentDidUpdate
pour les manipulations DOM comme celle-ci. Un shouldComponentUpdate
ne fera pas vraiment la différence pour un composant avec un seul enfant qui a toujours les mêmes accessoires. Vous devriez donc pouvoir l’enlever sans différence significative de performances.
Si vous avez profilé l'application et déterminé que dans ce cas particulier cela fait / fait une différence, vous pouvez hisser l'élément en constructeur.
De cette façon, React l’ignorera complètement (ce qui fonctionne effectivement de la même manière que 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;
}
}
Vous pouvez également le scinder en deux composants:
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)}
/>;
}
}
J'ai trouvé cela parce que j'avais une sorte de problème similaire mais pas complètement identique. La solution qui fonctionne pour moi consiste simplement à mettre tout le code pertinent dans shouldComponentUpdate
:
(l'instruction if
était auparavant dans componentWillReceiveProps
)
shouldComponentUpdate (nextProps, nextState) { // no more random renders
if (
(nextProps.nightMode !== this.props.nightMode) ||
(nextProps.language !== this.props.language)
) {
this.props.setRefresh(true) // setTimeout means after current operation
setTimeout(() => this.props.setRefresh(false), 1) // so loading will show for longer than 1ms
}
return this.props.refresh !== nextProps.refresh
}