171 votes

Dois-je utiliser un ou plusieurs useEffect dans le composant ?

J'ai des effets secondaires à appliquer et je veux savoir comment les organiser :

  • comme un effet à usage unique
  • ou plusieurs useEffects

Qu'est-ce qui est le mieux en termes de performances et d'architecture ?

262voto

Shubham Khatri Points 67350

Le modèle que vous devez suivre dépend de votre cas d'utilisation.

Premier Dans certains cas, il est nécessaire d'ajouter des récepteurs d'événements lors du montage initial et de les supprimer lors du démontage. Dans d'autres cas, un récepteur particulier doit être supprimé et ajouté à nouveau lors d'un changement d'accessoire. Dans un tel cas, il est préférable d'utiliser deux useEffect différents afin de conserver la logique pertinente et d'obtenir des avantages en termes de performances.

useEffect(() => {
   // adding event listeners on mount here
   return () => {
       // cleaning up the listeners here
   }
}, []);

useEffect(() => {
   // adding listeners everytime props.x changes
   return () => {
       // removing the listener when props.x changes
   }
}, [props.x])

Deuxièmement : Il peut arriver que vous deviez déclencher un appel à l'API ou un autre effet secondaire lorsque l'un des états ou des accessoires d'un ensemble change. Dans un tel cas, un seul useEffect avec les valeurs pertinentes à surveiller devrait être une bonne idée.

useEffect(() => {
    // side effect here on change of any of props.x or stateY
}, [props.x, stateY])

Troisièmement : Le troisième cas est celui où vous devez prendre des mesures différentes en cas de changement de valeurs différentes. Dans ce cas, séparez les comparaisons pertinentes en différentes valeurs. useEffects

useEffect(() => {
   // some side-effect on change of props.x
}, [props.x])

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])

1 votes

Qu'en est-il d'un terrain d'entente entre Deuxièmement y Troisièmement exemple ci-dessus : vous avez une logique qui s'exécute lorsqu'un sous-ensemble d'états/props change, mais chacun a une logique distincte qui doit s'exécuter en plus d'un code commun qui doit s'exécuter ? Vous n'utiliseriez pas [] (parce qu'il ne s'agit toujours que d'un sous-ensemble d'état/props pour lesquels vous attendez des modifications) mais vous aimeriez également réutiliser du code. Utilisez-vous des useEffects et mettre le code partagé dans une fonction qu'ils appellent chacun séparément ?

4 votes

Comme le suggère la réponse ci-dessous, l'équipe de React suggère de séparer les hooks par préoccupation, vous devez donc les diviser en de multiples useEffect appels.

81 votes

J'aime comment vous avez écrit useCase.

62voto

Guy Engel Points 1218

Vous devriez utiliser plusieurs effets pour séparer les préoccupations comme le suggère reactjs.org. https://reactjs.org/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns

3voto

Erik Points 1513

C'est parfaitement amende pour avoir des effets d'utilisation multiples.

Voici à quoi ressemble une de mes configurations :

/*
 * Backend tags list have changed add the changes if needed
 */
useEffect(() => {
    setTagsList(setTagsAdded);
}, [setTagsAdded]);

/*
 * Backend files have changed add the changes if needed
 */
useEffect(() => {
    for (let i = 0; i < changedFilesMeta.length; i += 1) {
        // Is the list item value changed
        if (changedFilesMeta[i].id === currentEditableFile.id) {
            unstable_batchedUpdates(() => {
                setTags(changedFilesMeta[i].tags ? changedFilesMeta[i].tags : []);
            });
        }
    }
}, [changedFilesMeta]);

/*
 * Reset when user select new files using the filepicker
 */
useEffect(() => {
    if (setNewFiles.length > 0) {
        unstable_batchedUpdates(() => {
            setCurrentFile(null);
            setDescription('');
            setTitle('');
            setTags([]);
        });
    }
}, [setNewFiles]);

/*
 * User selecet to edit a file, change to that file
 */
useEffect(() => {
    // When user select a file to edit it
    if (currentEditableFile && currentEditableFile !== theCurrentFile) {
        setCurrentFile(currentEditableFile);
        unstable_batchedUpdates(() => {
            setDescription(currentEditableFile.description);
            setTitle(currentEditableFile.title);
            setTags(currentEditableFile.tags);
        });
    }
}, [currentEditableFile]);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X