J'ai lu dans cet article React est lent, React est rapide: optimisation des applications React en pratique que:
En fait, chaque fois que vous passez un objet littéral comme accessoire à un composant enfant, vous cassez la pureté.
D'accord, j'ai compris. Donc, le mieux pour éviter cela est de créer une variable avec l'objet, et d'insérer cette variable dans le prop, comme ça:
import React from 'react'; class App extends React.Component { style = () => ({ marginTop: this.props.marginTop }) render() { return( <div style={this.style()}> </div> ) } }
Mais que se passe-t-il si le prop de style dépend d'un reçu un accessoire? Où devrait être l'objet? Par exemple, j'ai ce composant:
import React from 'react'; const style = (marginTop) => ({ marginTop }) const AnyComponent = (props) => ( <div style={style(props.marginTop)}> ... </div> )
Est-ce une bonne pratique à faire:
import React from 'react'; const AnyComponent = (props) => ( <div style={{ marginTop: props.marginTop }}> ... </div> )
[EDIT] J'ai oublié de dire que la plupart de mes composants ont un état, alors dans ce cas, est-ce une bonne idée de faire:
import React from 'react'; const style = { marginTop: 10 }; const AnyComponent = (props) => ( <div style={style}> ... </div> )
3 Réponses :
Vous pouvez créer votre variable dans votre composant, comme suit:
import React from 'react'; const AnyComponent = (props) => { // if props.marginTop is an object const style = props.marginTop; return ( <div style={style}> ... </div> )};
Cela crée-t-il une nouvelle variable de style
à chaque fois? L'objet style
précédent et le style
actuel auraient des adresses différentes, non?
Auparavant, vous ne pouviez pas faire cela dans les composants fonctionnels (bien que vous puissiez utiliser la mémorisation) Mais maintenant, grâce aux hooks React, vous pouvez faire quelque chose comme ceci:
import React from 'react'; const style = (marginTop) => ({ marginTop }) const AnyComponent = (props) => ( <div style={style(props.marginTop)}> ... </div> )
Et non, vous ne pouvez pas utiliser celui-ci:
const AnyComponent = (props) => { const style = useMemo(() => ({ marginTop: props.marginTop }), [props.marginTop]); <div style={style}> ... </div> }
Parce qu'il crée également un nouvel objet à chaque nouveau rendu d'AnyComponent en appelant la fonction de style à chaque fois.
useMemo
renvoie une valeur mémorisée, pas une fonction qui la renvoie. La suggestion avec getStyle
serait vraie pour useCallback
.
@estus Merci beaucoup pour votre commentaire. Je modifierai ma réponse
Un objet peut être mémorisé avec le hook useMemo
:
const AnyComponent = (({ marginTop }) => ( const style = useMemo(() => ({ marginTop }), [marginTop]); <div style={style}> ... </div> )
Puisque useMemo
est destiné à des calculs coûteux et a sa propre surcharge, cela peut être considéré comme une optimisation prématurée pour le cas div
.
merci pour votre réponse, que proposez-vous pour les composants de classe? J'ai édité mon message avec une proposition, qu'en pensez-vous?
useMemo
est spécifique aux composants fonctionnels. Vous pouvez utiliser un mémo à usage général comme Lodash. Comme je l'ai mentionné, cette optimisation n'a pas beaucoup de sens pour
@estus Pouvez-vous nous dire quels calculs coûteux sont nécessaires pour cela?
@EddieCooro Une fonction qui prend une quantité considérable de CPU ou de RAM, par exemple objet objet complexe.
Vous compliquez trop les choses. Avez-vous un problème de performances?
En fait, je le fais: mon application est assez grande (beaucoup plus grande que cela), utilise redux, et l'un de mes composants imbriqués profonds utilise draft-js. Je voudrais stocker l'EditorState dans mon magasin Redux pour plus de commodité, mais je ne peux pas le faire maintenant à cause des performances et de trop nombreux problèmes de restitution rendant l'éditeur de texte à la traîne. Je voudrais donner une chance à cette optimisation, car j'en ai déjà fait beaucoup plus (recomposer, resélectionner, etc.)