React Hooks - mit useState gegen nur Variablen


12

React Hooks geben uns die useState-Option, und ich sehe immer Vergleiche zwischen Hooks und Class-State. Aber was ist mit Hooks und einigen regulären Variablen?

Zum Beispiel,

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

Ich habe keine Hooks verwendet und es werden die gleichen Ergebnisse erzielt wie:

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

Was ist der Unterschied? Die Verwendung von Hooks ist in diesem Fall noch komplexer ... Warum also anfangen?


Sie vergleichen jedoch zwei verschiedene Dinge. Die zweite Funktion mit Hooks bietet die Möglichkeit, die Daten zu aktualisieren. Der erste macht eigentlich nichts. Sie hätten es einfach mit initialisieren können let a = 1; return <div>{a}</div>und Sie erhalten das gleiche Ergebnis.
Yathi

Antworten:


13

Der Grund ist, wenn Sie useStatedie Ansicht erneut rendern. Variablen selbst ändern nur die Bits im Speicher und der Status Ihrer App kann nicht mehr mit der Ansicht synchronisiert werden.

Vergleichen Sie diese Beispiele:

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>;
}

In beiden Fällen aändert sich useStateder aaktuelle Wert beim Klicken, aber nur, wenn Sie die Ansicht korrekt verwenden .


Vielen Dank! Wenn ich also die Ansicht nicht rendern muss - nur eine Möglichkeit, meine Daten (Requisiten) in einem Array zu organisieren - kann ich 'let' verwenden? Es funktioniert für mich, ich möchte nur wissen, ob es in Ordnung und akzeptabel ist.
Moshe Nagar

@MosheNagar Wenn Sie Ihre Daten von Requisiten ableiten, wird empfohlen, lokale Variablen zu verwenden, anstatt die Daten im Status zu halten, da die Komponente beim Requisitenwechsel ohnehin erneut gerendert wird, damit die Ansicht mit den Daten synchronisiert wird. Wenn Sie sie in den Status versetzen, wird dies nur zu unnötigem Rendern führen - zuerst beim Requisitenwechsel, dann beim Statuswechsel.
Marzelin

Eine weitere Möglichkeit, diese Antwort zu betrachten, besteht darin, zu denken, dass im zweiten Fall die Variable anach Abschluss der Ausführung als Müll gesammelt wird, während im ersten Fall useStateder Wert vona
João Marcos Gris

Er konnte es immer noch verwenden, useRefwenn er die Ansicht nicht erneut rendern wollte. Es bleibt die Frage, ob er lokale Variablen oder React-Referenzen verwenden soll. Wenn Sie beispielsweise eine Zeitüberschreitung haben, die Sie löschen müssen, oder eine laufende http-Anfrage mit Axios, speichern Sie die Zeitüberschreitung oder die Axios-Quelle in einer Variablen oder in einer React-Referenz?
Tom

3
@Tom Die allgemeine Regel lautet, lokale Variablen für den abgeleiteten Status zu verwenden. Für alles andere verwenden Sie useRef(wenn Sie kein erneutes Rendern möchten) oder useState(wenn Sie erneut rendern möchten). Im Falle von Timern sollten sie, da sie Nebenwirkungen sind, im useEffectHaken gestartet werden . Wenn Sie möchten , timerIdnur für die Bereinigung Zwecke, können Sie es in halten Handler ‚s lokale Variable. Wenn Sie den Timer von einer anderen Stelle in der Komponente löschen möchten, sollten Sie verwenden useRef. Das Speichern timerIdin der lokalen Variablen einer Komponente wäre ein Fehler, da lokale Variablen bei jedem Rendern "zurückgesetzt" werden.
Marzelin

1

Durch das Aktualisieren des Status wird die Komponente erneut gerendert, lokale Werte jedoch nicht.

In Ihrem Fall haben Sie diesen Wert in Ihrer Komponente gerendert. Das heißt, wenn der Wert geändert wird, sollte die Komponente neu gerendert werden, um den aktualisierten Wert anzuzeigen.

Es ist also besser zu verwenden useStateals der normale lokale Wert.

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>;
}

0

Ihr erstes Beispiel funktioniert nur, weil sich die Daten im Wesentlichen nie ändern. Der setStateEingabepunkt für die Verwendung ist das erneute Rendern Ihrer gesamten Komponente, wenn sich der Status ändert. Wenn für Ihr Beispiel eine Statusänderung oder -verwaltung erforderlich ist, werden Sie schnell feststellen, dass Änderungswerte erforderlich sind. Um die Ansicht mit dem Variablenwert zu aktualisieren, benötigen Sie den Status und das erneute Rendern.


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

ist äquivalent zu

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

Was useStatezurückkommt, sind zwei Dinge:

  1. neue Zustandsvariable
  2. Setter für diese Variable

Wenn Sie anrufen, rufen setA(1)Sie an this.setState({ a: 1 })und lösen ein erneutes Rendern aus.


0

Lokale Variablen werden bei jeder Mutation bei jeder Mutation zurückgesetzt, während der Status aktualisiert wird:

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>
  );
}

Bearbeiten Sie serene-galileo-ml3f0

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.