30 Minuten, um Ihnen ein umfassendes Verständnis von React Hooks zu vermitteln

30 Minuten, um Ihnen ein umfassendes Verständnis von React Hooks zu vermitteln

Überblick

1. Hooks können nur in Funktionskomponenten verwendet werden;

2. Hooks werden verwendet, um die Funktionalität von Funktionskomponenten zu erweitern, sodass Funktionskomponenten Klassenkomponenten vollständig ersetzen können

React Hooks sind alle an das React-Objekt angehängt, daher werden sie in Form von React.useState () verwendet. Wenn Sie Probleme haben, können Sie sie wie folgt im Voraus importieren:

importiere React, { useState } von "react"

React verfügt über viele integrierte Hooks. Hier sind einige häufig verwendete. Weitere Einzelheiten finden Sie unter Hooks API.

Der erste Buchstabe des Funktionskomponentennamens, der Hook verwendet, muss groß geschrieben werden, sonst meldet ESLint einen Fehler

1. useState

const [Zustand, festgelegter Zustand] = useState(Anfangszustand)

1.1 Drei Konzeptfragen

Was bewirkt der Aufruf von useState?

useState wird verwendet, um eine Statusvariable zu deklarieren und einen Status in eine Funktionskomponente einzuführen.

Welche Parameter übergeben wir an useState?

useState empfängt nur einen Parameter, der ein beliebiger Wert wie eine Zahl, eine Zeichenfolge, ein Objekt usw. sein kann, der zum Initialisieren der deklarierten Statusvariable verwendet wird. Es kann auch eine Funktion sein, die einen Anfangswert zurückgibt, vorzugsweise eine Funktion, die unnötige Berechnungen beim Rendern reduzieren kann.

Was gibt useState zurück?

Es gibt ein Lese-/Schreib-Array der Länge 2 zurück. Das erste Element des Arrays ist die definierte Statusvariable selbst und das zweite Element ist eine Funktion, die zum Aktualisieren der Statusvariable verwendet wird. Die Konvention ist das festgelegte Präfix plus der Name der Statusvariable. Wie setState empfängt die Funktion setState() einen Parameter, der der spezifische Wert nach der Aktualisierung oder eine Funktion sein kann, die den spezifischen Wert nach der Aktualisierung zurückgibt. Wenn setState eine Funktion empfängt, wird der alte Statuswert als Parameter an die empfangene Funktion übergeben und dann ein aktualisierter spezifischer Statuswert abgerufen.

1.2 Beispiel

Funktion App(){
  Konstante [n, setzeN] = Verwendungszustand(0)
  const [m, setM] = useState(() => 0)
  zurückkehren (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
      <br/>
      m: {m}
      <button onClick={() => setM(altesM => altesM+1)}>+1</button>
    </div>
  )
}

1.3 Hinweise

  • Der vom useState Hook zurückgegebene setState führt die Eigenschaften des Objektstatus nicht automatisch für uns zusammen
  • Wenn sich die Adresse des in „setState“ empfangenen Objektparameters nicht geändert hat, betrachtet React sie als unverändert und führt daher nicht zu einer Aktualisierung der Ansicht.

2. useReducer

useReducer ist eine aktualisierte Version von useState. In der von useState zurückgegebenen Schreibschnittstelle können wir nur das Endergebnis übergeben, und in setN handelt es sich nur um eine einfache Zuweisungsoperation.
Mit anderen Worten, der Berechnungsprozess zum Erhalten des Ergebnisses muss in die Rückruffunktion innerhalb der Funktionskomponente geschrieben werden, was zweifellos die Größe der Funktionskomponente erhöht und nicht der Idee von Flux entspricht (wer den Status generiert, ist für verschiedene Verarbeitungen verantwortlich und stellt die Verarbeitungsschnittstelle für andere zur Verwendung bereit).

Daher bietet React einen erweiterten Hook zur Statusverwaltung als useState: useReducer, der wie folgt eingeführt wird:

2.1 Nutzung

  • Erstellen Sie einen Anfangsstatuswert initialState
  • Erstellen Sie eine Reducer-Funktion (Status, Aktion), die alle Vorgänge enthält. Jeder Vorgangstyp gibt einen neuen Statuswert zurück.
  • Basierend auf initialState und Reducer verwenden Sie const [state, dispatch] = useReducer(reducer, initialState), um die Lese- und Schreib-API zu erhalten
  • Rufen Sie die Schreibschnittstelle auf, und die übergebenen Parameter werden alle an das Aktionsobjekt angehängt

2.2 Beispiel

importiere React, { useReducer } von 'react';
importiere ReactDOM von „react-dom“;

const initialState = {
  n: 0
}

const Reducer = (Status, Aktion) => {
  Schalter(Aktion.Typ){
    Fall „addOne“:
      return { n: Zustand.n + 1 }
    Fall 'addTwo':
      return { n: Zustand.n + 2 }
    Fall 'addX':
      return { n: Zustand.n + Aktion.x }
    Standard: {
      throw new Error('unbekannter Typ')
    }
  }
}

Funktion App(){
  const [Status, Versand] = useReducer(Reducer, Anfangsstatus)
  zurückkehren (
    <div>
      Ich bin App
      {Zustand.n}
      <button onClick={()=>dispatch({type: 'addOne'})}>+1</button>
      <button onClick={()=>dispatch({type: 'addTwo'})}>+2</button>
      <button onClick={()=>dispatch({type: 'addX', x: 5})}>+5</button>
    </div>
  )
}


ReactDOM.render(<App/>,document.getElementById('root'));

3. useContext

Kontext bedeutet Kontext. Kontext ist eine lokale globale Variable. Der lokale Gültigkeitsbereich wird vom Entwickler selbst festgelegt.

3.1 Nutzung

Die Verwendung von useContext gliedert sich in drei Schritte:

  • Verwenden Sie const x = createContext(null), um einen Kontext zu erstellen. Normalerweise wird beim Erstellen kein Anfangswert festgelegt, daher ist er null. Normalerweise wird er initialisiert, wenn der Kontextbereich angegeben wird.
  • Verwenden Sie <x.Provider value={}></x.Provider>, um den Kontext einzugrenzen
  • Verwenden Sie const value = useContext(x) im Bereich, um Kontextdaten zu verwenden

3.2 Beispiel

importiere React, { useState, createContext, useContext } von „react“;
importiere ReactDOM von „react-dom“;

const Context = erstelleKontext(null)

Funktion App(){
  Konstante [n, setzeN] = Verwendungszustand(0)
  zurückkehren (
    <Context.Provider-Wert={{n, setN}}>
      <div>
        <Baba />
        <Onkel />
      </div>
    </Context.Provider>
  )
}

Funktion Baba(){
  zurückkehren (
    <div>
      Ich bin ein Vater<Kind />
    </div>
  )
}

Funktion Onkel(){
  const {n, setN} = useContext(Kontext)
  zurückkehren (
    <div>
      Ich bin ein Onkel. Die Kontextdaten, die ich habe, sind {n}
    </div>
  )
}

Funktion Kind(){
  const {n, setN} = useContext(Kontext)
  zurückkehren (
    <div>
      Ich bin der Sohn. Die Kontextdaten, die ich habe, sind {n}
      <button bei Klick={() => setzeN(n+5)}>
        Klicken, um Kontextdaten zu ändern</button>
    </div>
  )
}


ReactDOM.render(<App/>,document.getElementById('root'));

4. useEffect

Wirkung bedeutet Nebenwirkung, und Veränderungen der Umwelt sind Nebenwirkungen. Nebeneffekte scheinen ein Konzept der funktionalen Programmierung zu sein. Ich werde es hier nicht im Detail erklären, da ich es nicht ganz verstehe.
In React ist useEffect eine Operation, die nach jedem Rendern ausgeführt wird, was afterRender entspricht. Der erste empfangene Parameter ist die Rückruffunktion und der zweite Parameter ist der Rückrufzeitpunkt. Kann verwendet werden, um den Lebenszyklus in Funktionskomponenten zu simulieren.

Wenn mehrere UseEffects gleichzeitig auftreten, werden sie in der Reihenfolge ausgeführt, in der sie auftreten.

4.1 componentDidMount simulieren

Effekt verwenden(()=>{
  console.log('Wird nur nach dem ersten Rendern ausgeführt')
},[])

4.2 Simulieren Sie componentDidMount + componentDidUpdate

Effekt verwenden(()=>{
   console.log('Nach jedem Rendern ausführen, einschließlich dem ersten Rendern')
})

4.3 Abhängigkeiten hinzufügen

Effekt verwenden(()=>{
    console.log('Wird nur ausgeführt, wenn sich x ändert, einschließlich der ersten Änderung von x von „undefined“ zu „initialValue“)
},[X])
//Wenn es zwei Abhängigkeiten gibt, wird es ausgeführt, wenn sich eine der beiden Abhängigkeiten ändert

4.4 Simulieren Sie componentWillUnmount

Effekt verwenden(()=>{
  console.log('Nach jedem Rendern ausführen, einschließlich dem ersten Rendern')
  Rückkehr ()=>{
    console.log('Die Komponente wird gleich zerstört.')
  }
})
//Gib einfach eine Funktion zurück, die ausgeführt wird, bevor die Komponente zerstört wird

5. useLayoutEffect

useEffect wird immer ausgeführt, nachdem der Browser die Ansicht gerendert hat. Wenn die Rückruffunktion in useEffect auf die DOM-Ansicht angewendet wird, wird die Ansicht zuerst initialisiert und dann der Rückruf in useEffect ausgeführt, der sofort einen Teil der Ansicht ändert, was zu einem flackernden Zustand führt.
Um dieses Flackern zu vermeiden, kann die Rückruffunktion des Nebeneffekts ausgeführt werden, bevor der Browser die Ansicht rendert. Wenn die Rückruffunktion, die den DOM im Effekt bedient, ausgeführt wird, bevor der DOM zur Anzeige auf der Seite bereitgestellt wird, tritt kein Flackern auf, nachdem der Browser die Seite gerendert hat.

Layout bedeutet Ansicht und useLayoutEffect ist der Nebeneffekt, der ausgeführt wird, bevor die Ansicht angezeigt wird.

Der Unterschied zwischen useEffect und useLayoutEffect ist die Ausführungszeit. useLayoutEffect wird ausgeführt, bevor der Browser rendert, während useEffect ausgeführt wird, nachdem der Browser rendert. Aber beide werden während der Ausführung der Renderfunktion ausgeführt. useEffect wird ausgeführt, nachdem das Rendern abgeschlossen ist, und useLayoutEffect wird ausgeführt, bevor das Rendern abgeschlossen ist (die Ansicht wurde nicht auf der Browserseite gerendert).

Daher wird useLayoutEffect immer vor useEffect ausgeführt.

Wenn die Rückruffunktion im Effekt Änderungen an der DOM-Ansicht beinhaltet, sollte im Allgemeinen useLayoutEffect verwendet werden. Wenn nicht, verwenden Sie useEffect.

6. useRef

Der useRef-Hook wird verwendet, um eine Variable zu definieren, die unverändert bleibt, wenn die Komponente kontinuierlich gerendert wird.
Jedes Mal, wenn eine Komponente gerendert wird, wird ein virtueller DOM zurückgegeben und die entsprechenden Variablen in der Komponente gehören in diesem Moment nur zum virtuellen DOM.
Der useRef-Hook bietet eine Möglichkeit, globale Variablen zu erstellen, die lokal für diese Komponente sind und während des gesamten Aktualisierungsverlaufs des virtuellen DOM bestehen bleiben.
Um sicherzustellen, dass die Variable, die durch useRef nach jedem Rendern erhalten wird, dieselbe Variable ist wie zuvor, kann dies nur durch die Verwendung von Referenzen erreicht werden. Daher speichert useRef den Wert dieser lokalen globalen Variable in einem Objekt mit dem Eigenschaftsnamen: current

useRef wird nicht automatisch gerendert, wenn aktuelle Änderungen

useRef kann das erstellte Refs-Objekt über das Ref-Attribut auf einen DOM-Knoten oder eine React-Instanz verweisen. Dieser Effekt wird in React eingeführt – Ref-Attribut.

Es kann auch als lokale globale Variable einer Komponente verwendet werden. Das folgende Beispiel zeichnet auf, wie oft die Seite gerendert wird.

Funktion App(){
  const [Status, Versand] = useReducer(Reducer, Anfangsstatus)
  Konstante Anzahl = useRef(0)
  Effekt verwenden(()=>{
    zählen.aktuell++;
    console.log(`Dies ist das ${count.current}te Mal, dass die Seite gerendert wird`)
  })
  zurückkehren (
    <div>
      Ich bin App
      {Zustand.n}
      <button onClick={()=>dispatch({type: 'addOne'})}>+1</button>
      <button onClick={()=>dispatch({type: 'addTwo'})}>+2</button>
      <button onClick={()=>dispatch({type: 'addX', x: 5})}>+5</button>
    </div>
  )
}

7. forwardRef (kein Hook)

forwardRef wird hauptsächlich verwendet, um native Funktionskomponenten, die das ref-Attribut nicht unterstützen, zu verpacken, damit sie das ref-Attribut empfangen können. Informationen zur spezifischen Verwendung finden Sie unter React—ref-Attribut

forwardRef empfängt eine Funktionskomponente und gibt eine Funktionskomponente zurück, die das Ref-Attribut empfangen kann

8. useMemo und useCallback

Das React-Framework erhält durch kontinuierliches Rendern verschiedene virtuelle DOMs und führt dann DOM Diff aus, um das Seiten-DOM selektiv zu aktualisieren. Daher gibt es nach jedem Rendern für kurze Zeit zwei neue und alte virtuelle DOMs.

Wenn eine Komponente untergeordnete Komponenten enthält und die übergeordnete Komponente das Rendern auslöst, wird die untergeordnete Komponente aufgrund des erneuten Renderns der übergeordneten Komponente erneut gerendert, auch wenn sich die Eigenschaften, von denen die untergeordnete Komponente abhängt, nicht geändert haben. Dies führt zu unnötigem Rendering.

Um unnötiges Rendern zu vermeiden, stellt React die Schnittstelle React.memo() bereit, um Unterkomponenten zu kapseln. wie folgt:

Funktion App(){
  Konstante [n, setzeN] = Verwendungszustand(0)
  const [m, setzeM] = useState(0)
  zurückkehren (
    <div>
      Ich bin die übergeordnete Komponente n: {n}
      <button onClick={()=>setN(n+1)}>n+1</button>
      <button onClick={()=>setM(m+1)}>m+1</button>
      <Child value={m}/> // Auf diese Weise wird die untergeordnete Komponente nicht erneut gerendert, wenn sich der m-Wert, von dem die untergeordnete Komponente abhängt, nicht ändert.
    </div>
  )
}

const Child = React.memo((Eigenschaften)=>{
  Effekt verwenden(()=>{
    console.log('Unterkomponente gerendert')
  })
  zurückkehren (
  <div>Ich bin eine untergeordnete Komponente und der Wert, den ich von der übergeordneten Komponente erhalte, ist: m {props.value}</div>
  )
})

Die obige Methode weist jedoch einen Fehler auf, da React.memo nur die vorherigen und nächsten Werte vergleicht, um festzustellen, ob sich die Eigenschaften der Abhängigkeiten der untergeordneten Komponente geändert haben. Wenn die Abhängigkeit, die die untergeordnete Komponente von der übergeordneten Komponente erhält, ein Objekt ist, wird die Adresse des Objekts verglichen, nicht der Inhalt innerhalb des Objekts. Daher wird bei jedem erneuten Rendern der übergeordneten Komponente ein Objekt mit einer anderen Adresse erhalten. Obwohl der Wert im Objekt nicht aktualisiert wurde, wird die untergeordnete Komponente erneut gerendert, wenn sie feststellt, dass sich die Adresse geändert hat.

Um dieses Problem zu lösen, wurde der useMemo()-Hook eingeführt. useMemo wird verwendet, um eine Funktion oder ein Objekt beim Wechsel zwischen alten und neuen Komponenten zwischenzuspeichern und wiederzuverwenden und es nur dann neu zu generieren, wenn sich eine Abhängigkeit erneut ändert.

Der useMemo-Hook nimmt eine Funktion, die eine Funktion (oder ein Objekt) ohne Argumente zurückgibt. Und useMemo muss über eine Abhängigkeit verfügen, die ihm mitteilt, wann eine Neuberechnung erfolgen soll. Es ähnelt in gewisser Weise dem Prinzip der berechneten Eigenschaften von Vue. wie folgt:

Funktion App(){
  Konstante [n, setzeN] = Verwendungszustand(0)
  const [m, setzeM] = useState(0)
  const beiClickChild = useMemo(()=>{
    zurückgeben () => {
      console.log(m)
    }
  },[M])  
  zurückkehren (
    <div>
      Ich bin die übergeordnete Komponente n: {n}
      <button onClick={()=>setN(n+1)}>n+1</button>
      <button onClick={()=>setM(m+1)}>m+1</button>
      <Untergeordneter Wert = {m} bei Klick = {bei Klick untergeordnet}/>
    </div>
  )
}

const Child = React.memo((Eigenschaften)=>{
  Effekt verwenden(()=>{
    console.log('Unterkomponente gerendert')
  })
  zurückkehren (
    <div>
      Ich bin eine untergeordnete Komponente und erhalte den Wert von der übergeordneten Komponente als: m {props.value}
      <br/>
      <button onClick={props.onClick}>Klick</button>
    </div>
  )
})

useCallback() ist die Syntaxvereinfachung von useMemo. Da useMemo eine Funktion empfängt, die eine Funktion (oder ein Objekt) ohne Parameter zurückgibt, wäre das etwas seltsam, daher wird useCallback bereitgestellt, um Funktionen oder Objekte direkt zu empfangen.

const onClickChild = useMemo(() => {
      console.log(m)
  },[M])

9. useInperativeHandle

useInperativeHandel ist ein mit ref verknüpfter Hook.

Wir wissen, dass das Ref-Attribut die aktuelle Komponenteninstanz oder das native DOM direkt der aktuellen Eigenschaft des übergebenen Ref-Objekts zuweist und Funktionskomponenten das Ref-Attribut nicht erhalten können, da Funktionskomponenten keine Instanzen haben. Wenn die Funktionskomponente jedoch einen Verweis empfangen kann, nachdem sie von React.forwardRef() gekapselt wurde, greift dieser Verweis im Allgemeinen auf das native DOM zu, nachdem er von der Funktionskomponente weitergeleitet wurde. Aber was ist, wenn der externe Verweis auf mehr als nur ein natives DOM in der Funktionskomponente verweisen soll? Ist es möglich, dem Verweis einer Funktionskomponente besser steuerbare Operationen zuzuweisen, so wie dem Verweis in einer Klassenkomponente, die auf eine Instanz verweist? React bietet Funktionskomponenten eine Möglichkeit, das Objekt zu kapseln, auf das der zurückgegebene Verweis verweist. Dabei handelt es sich um den useInteractiveHandle-Hook.

9.1 Ein Beispiel

Funktion App(){
  const myRef = useRef(null)
  Effekt verwenden(()=>{
    Konsole.log(myRef.current.real)
    Konsole.log(myRef.current.getParent())
  }, [])
  zurückkehren (
    <div>
      Ich bin die übergeordnete Komponente <Child ref={myRef}/>
    </div>
  )
}

const Child = vorwärtsRef((Eigenschaften, Ref)=>{
  const childRef = useRef(null)
  useImperativeHandle(ref, ()=>{
    zurückkehren {
      real: childRef.current,
      getParent(){
        gibt childRef.current.parentNode zurück
      }
    }
  })
  zurückkehren (
    <div>
      Ich bin eine untergeordnete Komponente und habe ein untergeordnetes DOM
      <button ref={childRef}>Schaltfläche</button>
    </div>
  )
})

10. Benutzerdefinierte Haken

Ein benutzerdefinierter Hook ist eine benutzerdefinierte Funktion. Diese Funktion muss mit use gestartet werden und in der Funktion müssen native Ract-Hooks verwendet werden. Der Rückgabewert ist im Allgemeinen ein Array oder ein Objekt, das verwendet wird, um die Lese- und Schreibschnittstelle der Hooks verfügbar zu machen.

Benutzerdefinierte Hooks integrieren normalerweise die mehrfach verwendeten Hooks in Funktionskomponenten. Versuchen Sie, mehrere Hook-Operationen in Funktionskomponenten zu vermeiden.

Das Obige ist der detaillierte Inhalt von 30 Minuten, um React Hooks vollständig zu verstehen. Weitere Informationen zum vollständigen Verständnis von React Hooks finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung zum Übergeben von Werten zwischen React-Hook-Komponenten (mithilfe von ts)
  • ReactHooks Batch-Update-Status und Abrufen von Routenparametern Beispielanalyse
  • Detaillierte Erklärung zu React Hooks
  • Häufige Fehler bei der Verwendung von React Hooks
  • So funktionieren React Hooks
  • Häufige Verwendung von Hooks in React
  • Einführung in 10 Hooks in React

<<:  Python 3.7-Installationstutorial für MacBook

>>:  Eine einfache Erklärung der parallelen MySQL-Replikation

Artikel empfehlen

Erfahren Sie, wie Sie Docker unter Windows 10 Home Edition installieren.

Als ich die Bücher über Redis und Spring Cloud Al...

Detaillierte Erläuterung des MySQL-Isolationsebenen-Operationsprozesses (cmd)

Beispielvorgang für nicht festgeschriebenes Lesen...

Beispiel zum Erstellen und Ausführen mehrerer MySQL-Container in Docker

1. Verwenden Sie das Image mysql/mysql-server:lat...

MySQL-Optimierung: Cache-Optimierung (Fortsetzung)

In MySQL gibt es überall Caches. Wenn ich den Que...

MySQL Dezimalzahl unsigned Update negative Zahlen in 0 umgewandelt

Heute habe ich bei der Überprüfung des Parallelit...

So steuern Sie den Anteil untergeordneter Flex-Elemente auf der Hauptachse

Hintergrund Durch das flexible Layout wird eine e...

Einführung in die Cloud-native-Technologie Kubernetes (K8S)

Inhaltsverzeichnis 01 Was ist Kubernetes? 02 Der ...

MySQL-Datenbankoperationen und Datentypen

Inhaltsverzeichnis 1. Datenbankbetrieb 1.1 Datenb...