2
votes

Fonctionnement de la fonction `useState` dans la fonction` useEffect`

J'essaie d'utiliser useState dans useEffect . Je veux accéder et modifier un état à l'intérieur ( useEffect ), ici nommé isAuth et en fonction du nouvel état, rendre le composant.

import React, { useState, useEffect } from 'react';

const Authentication = () => {
    const [isAuth, setIsAuth] = useState(false);

    useEffect(() => {
        console.log(isAuth);
        setIsAuth(true);
        console.log(isAuth);
    }, [isAuth]);
    return <div>{isAuth ? <p>True</p> : <p>False</p>}</div>;
};

export default Authentication;

Le truc est dans la console, je reçois false , false , true , true . Au lieu de cela console, je m'attendais à ce que le deuxième message de la console soit vrai. Quelqu'un peut-il expliquer comment cela se passe et comment modifier l'état avant le rendu du composant?


0 commentaires

3 Réponses :


5
votes

setIsAuth ne provoque pas la modification de sa valeur par la variable locale isAuth . Les const ne peuvent pas changer leur valeur, et même si vous l'avez définie comme let , ce n'est pas ce que fait l'état des paramètres. Au lieu de cela, lorsque vous définissez l'état, le composant est réémis. Sur ce nouveau rendu, l'appel à useState renverra la nouvelle valeur, et vous pouvez utiliser cette nouvelle valeur pour le nouveau rendu.


7 commentaires

Pouvez-vous s'il vous plaît préciser votre explication en donnant un exemple?


"Les effets" voient "toujours les accessoires et l'état à partir du rendu dans lequel ils ont été définis." donc chaque rendu a ses propres accessoires et état. Je recommande de lire ceci pour plus d'informations: overreacted.io/a-complete-guide-to -useeffect


ok, je pense que ce que vous essayez de dire, c'est que le composant est rendu pour la première fois sans exécuter la fonction setState .


Le composant est rendu pour la première fois. Ensuite, il exécute l'effet. La fermeture de l'effet a les variables locales de ce premier rendu, et votre code utilise ces variables pour enregistrer le faux deux fois. Puisque vous avez appelé set state, un nouveau rendu se produira, et ce nouveau rendu aura des variables différentes. Quand son effet s'exécute, il enregistrera true deux fois, puisque ce sont les valeurs de sa fermeture.


Merci :) pour votre explication, j'ai compris le point que vous essayez de faire valoir, mais pouvez-vous me dire s'il existe un moyen par lequel je peux changer mon état par défaut avant de le rendre pour la première fois.


Eh bien, vous pouvez passer une valeur différente à useState. C'est ce que tu veux dire? Si cela nécessite un calcul synchrone, faites-le simplement dans le corps du composant avant d'appeler useState. Si cela nécessite un calcul asynchrone, vous ne pouvez pas le faire, pas avec un seul composant. Vous pourriez avoir un composant wrapper qui effectue le travail asynchrone, et ce n'est qu'une fois ce travail terminé qu'il rend un composant enfant et lui passe un accessoire. Comme l'enfant n'est jamais rendu tant que cet accessoire n'est pas disponible, l'enfant l'aura dès son premier rendu.


Merci encore, oui, il s'agissait de faire les deux, un travail asynchrone et un travail de synchronisation. J'ai compris maintenant comment y faire face.



0
votes

Voici quelques commentaires dans le code expliquant comment React setState ne mettra à jour le const local qu'une fois que le composant sera de nouveau rendu

import React, { useState, useEffect } from 'react';

const Authentication = () => {
    // React will initialise `isAuth` as false
    const [isAuth, setIsAuth] = useState(false);

    useEffect(() => {
        // Console log outputs the initial value, `false`
        console.log(isAuth);
        // React sets state to true, but the new state is not available until
        // `useState` is called on the next render
        setIsAuth(true);

        // `isAuth` will remain false until the component re-renders
        // So console.log will output `false` again the first time this is called
        console.log(isAuth);
    }, [isAuth]);

    // The first time this is rendered it will output <p>False</p>

    // There will be a re-render after the `setState` call and it will
    // output <p>True</p> 
    return <div>{isAuth ? <p>True</p> : <p>False</p>}</div>;
};

export default Authentication;


0 commentaires

0
votes

C'est en fait correct. useEffect vous permet d'accéder au dernier état après une mise à jour. Ainsi, lors du premier rendu, ce que vous voyez est fondamentalement l'état initial, peu importe si vous le mettez à jour.

L'appel de setState à l'intérieur de useEffect provoquera un rerender avec le nouvel état ( isAuth = true ), ce qui entraînera un nouvel appel de useEffect. À ce stade, le nouvel état de journalisation est vrai.


0 commentaires