Existe-t-il une approche systématique pour déboguer ce qui cause la restitution d'un composant dans React? Je mets un simple console.log () pour voir combien de fois il est rendu, mais j'ai du mal à comprendre ce qui provoque le rendu du composant plusieurs fois, c'est-à-dire (4 fois) dans mon cas. Existe-t-il un outil existant qui affiche un plan de montage chronologique et / ou l’arborescence de tous les composants?
Réponses
Trop de publicités?Si vous voulez un extrait court sans aucune dépendance externe, je trouve cela utile
componentDidUpdate(prevProps, prevState) {
Object.entries(this.props).forEach(([key, val]) =>
prevProps[key] !== val && console.log(`Prop '${key}' changed`)
);
Object.entries(this.state).forEach(([key, val]) =>
prevState[key] !== val && console.log(`State '${key}' changed`)
);
}
Voici un petit crochet que j'utilise pour suivre les mises à jour des composants de la fonction
function useTraceUpdate(props) {
const prev = useRef(props);
useEffect(() => {
const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
if (prev.current[k] !== v) {
ps[k] = [prev.current[k], v];
}
return ps;
}, {});
if (Object.keys(changedProps).length > 0) {
console.log('Changed props:', changedProps);
}
prev.current = props;
});
}
Voici quelques instances que Réagir composante sera de nouveau rendu.
- Composant Parent rerender
- Appelant
this.setState()
au sein de la composante. Cela va déclencher le composant suivant du cycle de vie des méthodes d'shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
- Les changements dans la composante de l'
props
. Cela va déclenchercomponentWillReceiveProps
>shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
(connect
méthode dereact-redux
déclencheur de cette quand il y a des changements dans le Redux magasin) - appelant
this.forceUpdate
qui est similaire à l'this.setState
Vous pouvez réduire votre composant rerender par la mise en œuvre d'une case à l'intérieur de votre shouldComponentUpdate
et de revenir false
si il n'est pas nécessaire.
Une autre façon est d'utiliser des React.PureComponent
ou apatrides composants. Pure et apatrides uniquement les composants de re-rendre quand il y a des changements à ses accessoires.
@jpdelatorre la réponse est grande à mettre en évidence les raisons pourquoi Réagir composant de re-rendre.
Je voulais juste de plonger un peu plus profondément dans un cas: lorsque des accessoires de changer. Dépannage ce qui est à l'origine de Réagir composant à nouveau le rendu est un problème commun, et dans mon expérience, beaucoup de temps la traque de cette question consiste à déterminer quels accessoires sont en train de changer.
Réagir composants de rendre à nouveau chaque fois qu'ils reçoivent de nouveaux accessoires. Ils peuvent recevoir de nouveaux accessoires comme:
<MyComponent prop1={currentPosition} prop2={myVariable} />
ou si MyComponent
est connecté à un redux du magasin:
function mapStateToProps (state) {
return {
prop3: state.data.get('savedName'),
prop4: state.data.get('userCount')
}
}
À tout moment la valeur de prop1
, prop2
, prop3
ou prop4
change MyComponent
re-rendu. Avec 4 accessoires, il n'est pas trop difficile de traquer les accessoires qui sont en train de changer en mettant un console.log(this.props)
au début de l' render
bloc. Cependant, avec plus compliqué de composants et de plus en plus des accessoires de cette méthode est intenable.
Ici est une approche utile (à l'aide de lodash pour des raisons de commodité) afin de déterminer les prop changements sont à l'origine d'un composant afin de rendre à nouveau:
componentWillReceiveProps (nextProps) {
const changedProps = _.reduce(this.props, function (result, value, key) {
return _.isEqual(value, nextProps[key])
? result
: result.concat(key)
}, [])
console.log('changedProps: ', changedProps)
}
L'ajout de cet extrait de votre composant peut aider à révéler le coupable causant discutable re-rend, et de nombreuses fois, cela permet de faire la lumière sur les données inutiles adduction dans les composants.
Les réponses ci-dessus sont très utiles, juste au cas où si quelqu'un est à la recherche d'une méthode spécifique pour détecter la cause de rerender puis j'ai trouvé cette bibliothèque redux-enregistreur de très utile.
Ce que vous pouvez faire est d'ajouter la bibliothèque et de permettre la comparaison entre l'état(c'est là, dans les docs) comme:
const logger = createLogger({
diff: true,
});
Et ajouter le middleware dans le magasin.
Ensuite, mettre un console.log()
dans la fonction rendu du composant que vous souhaitez tester.
Ensuite, vous pouvez exécuter votre application et consulter les journaux de la console.Partout où il y a un journal juste avant, il va vous montrer la différence entre l'état (nextProps and this.props)
et vous pouvez décider si le rendu est vraiment nécessaire
Il sera semblable à l'image ci-dessus avec les diff clé.