React Hooks - en utilisant les variables useState vs just

12

React Hooks nous donne l'option useState, et je vois toujours des comparaisons Hooks vs Class-State. Mais qu'en est-il des crochets et de certaines variables régulières?

Par exemple,

function Foo() {
    let a = 0;
    a = 1;
    return <div>{a}</div>;
}

Je n'ai pas utilisé de crochets, et cela me donnera les mêmes résultats que:

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

Alors quelle est la différence? Utiliser des crochets encore plus complexes pour ce cas ... Alors pourquoi commencer à l'utiliser?

Moshe Nagar
la source
Vous comparez cependant 2 choses différentes. La deuxième fonction avec crochets a la possibilité de mettre à jour les données. Le premier ne fait vraiment rien. Vous auriez pu l'initialiser avec let a = 1; return <div>{a}</div>et vous obtiendrez le même résultat.
Yathi

Réponses:

13

La raison en est que si vous useStaterestituez la vue. Les variables seules ne modifient que les bits en mémoire et l'état de votre application peut se désynchroniser avec la vue.

Comparez ces exemples:

function Foo() {
    const [a, setA] = useState(0);
    return <div onClick={() => setA(a + 1)}>{a}</div>;
}

function Foo() {
    let a = 0;
    return <div onClick={() => a + 1}>{a}</div>;
}

Dans les deux cas, les amodifications au clic, mais uniquement lorsque vous utilisez useStatecorrectement la vue, affichent ala valeur actuelle de.

marzelin
la source
Merci! Donc, si je n'ai pas besoin de rendre la vue - seulement un moyen d'organiser mes données (accessoires) dans un tableau - je peux utiliser 'let'? Cela fonctionne pour moi, je veux juste savoir que c'est correct et acceptable.
Moshe Nagar
@MosheNagar si vous dérivez vos données à partir d'accessoires, il est recommandé d'utiliser des variables locales au lieu de garder les données en état car le composant se rendra de nouveau sur le changement d'accessoire de sorte que la vue sera synchronisée avec les données. Les mettre en état ne provoquerait qu'un rendu inutile - d'abord sur le changement d'hélice, puis sur le changement d'état.
marzelin
Une autre façon de voir cette réponse est de penser que dans le second cas, la variable asera récupérée après la fin de son exécution, tandis que dans le premier, car elle tire parti de useStatela valeur dea
João Marcos Gris
Il pourrait toujours l'utiliser useRefs'il ne voulait pas restituer la vue. La question reste de savoir s'il doit utiliser des variables locales ou des références React. Par exemple, si vous avez un délai d'attente que vous devez effacer, ou une demande http en cours utilisant axios, stockez-vous le délai d'attente ou la source axios dans une variable ou dans une référence React?
Tom
3
@Tom La règle générale est d'utiliser des variables locales pour l'état dérivé. Pour toute autre chose, utilisez useRef(si vous ne voulez pas de rendu) ou useState(si vous voulez de nouveau). Dans le cas des minuteries, car ce sont des effets secondaires, elles doivent être démarrées en useEffectcrochet. Si vous le souhaitez timerIduniquement à des fins de nettoyage, vous pouvez le conserver dans la variable locale du gestionnaire . Si vous voulez pouvoir effacer la minuterie d'un autre endroit du composant, vous devez utiliser useRef. Le stockage timerIddans la variable locale d' un composant serait une erreur car les variables locales sont "réinitialisées" sur chaque rendu.
marzelin
1

La mise à jour de l'état entraînera un nouveau rendu du composant, mais les valeurs locales ne le sont pas.

Dans votre cas, vous avez rendu cette valeur dans votre composant. Cela signifie que lorsque la valeur est modifiée, le composant doit être restitué pour afficher la valeur mise à jour.

Il sera donc préférable d'utiliser useStateune valeur locale normale.

function Foo() {
    let a = 0;
    a = 1; // there will be no re-render.
    return <div>{a}</div>;
}

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // re-render required
    return <div>{a}</div>;
}
diamant
la source
0

Votre premier exemple ne fonctionne que parce que les données ne changent pratiquement jamais. Le point d'entrée de l'utilisation setStateest de restituer l'intégralité de votre composant lorsque l'état se bloque. Donc, si votre exemple nécessitait une sorte de changement d'état ou de gestion, vous réaliserez rapidement que les valeurs de changement seront nécessaires et pour mettre à jour la vue avec la valeur variable, vous aurez besoin de l'état et du rendu.

10100111001
la source
0
function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

est équivalent à

class Foo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            a: 0
        };
    }
    // ...
}

Quels useStateretours sont deux choses:

  1. nouvelle variable d'état
  2. setter pour cette variable

si vous appelez, setA(1)vous appelez this.setState({ a: 1 })et déclenchez un nouveau rendu.

schogges
la source
0

Les variables locales seront réinitialisées à chaque rendu lors d'une mutation tandis que l'état sera mis à jour:

function App() {
  let a = 0; // reset to 0 on render/re-render
  const [b, setB] = useState(0);

  return (
    <div className="App">
      <div>
        {a}
        <button onClick={() => a++}>local variable a++</button>
      </div>
      <div>
        {b}
        <button onClick={() => setB(prevB => prevB + 1)}>
          state variable b++
        </button>
      </div>
    </div>
  );
}

Modifier serene-galileo-ml3f0

Drew Reese
la source