React Hooks: The Deep Cuts PlatoBlockchain-Datenintelligenz. Vertikale Suche. Ai.

Reaktionshaken: Die tiefen Schnitte

Hooks sind wiederverwendbare Funktionen. Sie erlauben Ihnen zu verwenden Zustand und andere Funktionen (z. B. Lebenszyklusmethoden usw.), ohne eine Klasse zu schreiben. Hook-Funktionen lassen uns „einhaken“. Lebenszyklus des Reaktionszustands Verwendung von funktionalen Komponenten, die es uns ermöglichen, den Zustand unserer funktionalen Komponenten zu manipulieren, ohne sie in Klassenkomponenten konvertieren zu müssen.

Reagieren Haken eingeführt zurück in Version 16.8 und hat seitdem immer mehr hinzugefügt. Einige sind häufiger und beliebter als andere, wie z useEffect, useState und useContext Haken. Ich habe keinen Zweifel, dass Sie nach diesen gegriffen haben, wenn Sie mit React arbeiten.

Was mich aber interessiert, sind die weniger bekannten React-Hooks. Während alle React-Hooks auf ihre eigene Weise interessant sind, gibt es fünf davon, die ich Ihnen wirklich zeigen möchte, weil sie in Ihrer täglichen Arbeit vielleicht nicht auftauchen – oder vielleicht tun sie es und wenn Sie sie kennen, erhalten Sie einige zusätzliche Superkräfte.

Inhaltsverzeichnis

useReducer

Das useReducer Hook ist wie andere Hooks ein Zustandsverwaltungstool. Insbesondere ist es eine Alternative zum useState Haken.

Wenn Sie die useReducer Hook verwenden, um zwei oder mehr Zustände (oder Aktionen) zu ändern, müssen Sie diese Zustände nicht einzeln manipulieren. Der Hook verfolgt alle Zustände und verwaltet sie gemeinsam. Mit anderen Worten: Es verwaltet und rendert Zustandsänderungen neu. im Gegensatz zu den useState Haken, useReducer ist einfacher, wenn es darum geht, viele Zustände in komplexen Projekten zu handhaben.

Anwendungsszenarien

useReducer kann dazu beitragen, die Komplexität der Arbeit mit mehreren Zuständen zu reduzieren. Verwenden Sie es, wenn Sie feststellen, dass Sie mehrere Status gemeinsam verfolgen müssen, da es Ihnen ermöglicht, die Statusverwaltung und die Rendering-Logik einer Komponente als separate Anliegen zu behandeln.

Syntax

useReducer akzeptiert drei Argumente, von denen eines optional ist:

  • eine Reduzierfunktion
  • initialState
  • an init Funktion (optional)
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction) // in the case where you initialize with the optional 3rd argument

Beispiel

Das folgende Beispiel ist eine Schnittstelle, die eine Texteingabe, einen Zähler und eine Schaltfläche enthält. Die Interaktion mit jedem Element aktualisiert den Status. Beachte wie useReducer ermöglicht es uns, mehrere Fälle auf einmal zu definieren, anstatt sie einzeln einzurichten.

import { useReducer } from 'react';
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    case 'USER_INPUT':
      return { ...state, userInput: action.payload };
    case 'TOGGLE_COLOR':
      return { ...state, color: !state.color };
    default:
      throw new Error();
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, { count: 0, userInput: '', color: false })

  return (
    <main className="App, App-header" style={{ color: state.color ? '#000' : '#FF07FF'}}>
      <input style={{margin: '2rem'}}
        type="text"
        value={state.userInput}
        onChange={(e) => dispatch({ type: 'USER_INPUT', payload: e.target.value })}
      />
      <br /><br />
      <p style={{margin: '2rem'}} >{state.count}</p>
      <section style={{margin: '2rem'}}>
        <button  onClick={(() => dispatch({ type: 'DECREMENT' }))}>-</button>
        <button onClick={(() => dispatch({ type: 'INCREMENT' }))}>+</button>
        <button onClick={(() => dispatch({ type: 'TOGGLE_COLOR' }))}>Color</button>
      </section>
      <br /><br />
      <p style={{margin: '2rem'}}>{state.userInput}</p>
    </main>
  );
}
export default App;

Aus dem obigen Code ist ersichtlich, wie wir in der Lage sind, mehrere Zustände einfach zu verwalten Reduzierstück (Switch-Case), dies zeigt den Vorteil der useReducer. Dies ist die Leistung, die es bietet, wenn Sie in komplexen Anwendungen mit mehreren Zuständen arbeiten.

useRef

Das useRef Hook wird verwendet, um Verweise auf Elemente zu erstellen, um auf das DOM zuzugreifen. Aber darüber hinaus gibt es ein Objekt mit a zurück .current Eigenschaft, die während des gesamten Lebenszyklus einer Komponente verwendet werden kann, sodass Daten beibehalten werden können, ohne ein erneutes Rendern zu verursachen. Also, die useRef der Wert bleibt zwischen den Rendervorgängen gleich; Das Aktualisieren der Referenz löst kein erneutes Rendern aus.

Anwendungsszenarien

Greifen Sie nach dem useRef Haken, wenn Sie wollen:

  • Manipulieren Sie das DOM mit gespeicherten veränderlichen Informationen.
  • Greifen Sie auf Informationen von untergeordneten Komponenten (verschachtelte Elemente) zu.
  • Fokus auf ein Element setzen.

Dies ist am nützlichsten, wenn Sie veränderliche Daten in Ihrer App speichern, ohne ein erneutes Rendern zu verursachen.

Syntax

useRef akzeptiert nur ein Argument, nämlich das Ursprünglicher Wert.

const newRefComponent = useRef(initialValue);

Beispiel

Hier habe ich die verwendet useRef und useState Hook, um anzuzeigen, wie oft eine Anwendung einen aktualisierten Status rendert, wenn sie eine Texteingabe eingibt.

import './App.css'

function App() {
  const [anyInput, setAnyInput] = useState(" ");
  const showRender = useRef(0);
  const randomInput = useRef();
  const toggleChange = (e) => {
    setAnyInput (e.target.value);
    showRender.current++;
  
  }
  const focusRandomInput = () => {
    randomInput.current.focus();
  }

  return (
    <div className="App">
      <input className="TextBox" 
        ref ={randomInput} type="text" value={anyInput} onChange={toggleChange}
      />
      <h3>Amount Of Renders: {showRender.current}</h3>
      <button onClick={focusRandomInput}>Click To Focus On Input </button>
    </div>
  );
}

export default App;

Beachten Sie, wie die Eingabe jedes Zeichens in das Textfeld den Status der App aktualisiert, aber niemals eine vollständige Neudarstellung auslöst.

useImperativeHandle

Sie wissen, wie eine untergeordnete Komponente Zugriff auf Aufruffunktionen hat, die von der übergeordneten Komponente an sie weitergegeben wurden? Eltern geben diese über Props weiter, aber diese Übertragung ist „unidirektional“ in dem Sinne, dass der Elternteil keine Funktion aufrufen kann, die sich im Kind befindet.

Nun, useImperativeHandle ermöglicht es einem übergeordneten Element, auf die Funktionen einer untergeordneten Komponente zuzugreifen.

Wie funktioniert das?

  • In der untergeordneten Komponente wird eine Funktion definiert.
  • A ref wird im Elternteil hinzugefügt.
  • Wir verwenden forwardRef, erlauben die ref die definiert wurde, um an das Kind weitergegeben zu werden.
  • useImperativeHandle macht die Funktionen des Kindes über die verfügbar ref.

Anwendungsszenarien

useImperativeHandle funktioniert gut, wenn Sie möchten, dass eine übergeordnete Komponente von Änderungen in der untergeordneten Komponente beeinflusst wird. So können Dinge wie ein geänderter Fokus, Inkrementieren und Dekrementieren und unscharfe Elemente Situationen sein, in denen Sie nach diesem Haken greifen, damit der Elternteil entsprechend aktualisiert werden kann.

Syntax

useImperativeHandle (ref, createHandle, [dependencies])

Beispiel

In diesem Beispiel haben wir zwei Schaltflächen, eine in einer übergeordneten Komponente und eine in einer untergeordneten Komponente. Durch Klicken auf die übergeordnete Schaltfläche werden Daten von der untergeordneten Komponente abgerufen, sodass wir die übergeordnete Komponente manipulieren können. Es ist so eingerichtet, dass beim Klicken auf die untergeordnete Schaltfläche nichts von der übergeordneten Komponente an die untergeordnete Komponente weitergegeben wird, um zu veranschaulichen, wie wir Dinge in die entgegengesetzte Richtung weitergeben.

// Parent component
import React, { useRef } from "react";
import ChildComponent from "./childComponent";
import './App.css';

function useImperativeHandle() {
  const controlRef = useRef(null);
  return (
    onClick={
      () => {
        controlRef.current.controlPrint();
      }
    }
    >
    Parent Box
  );
}
export default useImperativeHandle;
// Child component
import React, { forwardRef, useImperativeHandle, useState } from "react";

const ChildComponent = forwardRef((props, ref) => {
  const [print, setPrint] = useState(false);
  useImperativeHandle(ref, () => ({
    controlPrint() 
    { setPrint(!print); },
  })
  );

  return (
    <>
    Child Box
    { print && I am from the child component }
  );
});

export default ChildComponent;

Output

useMemo

useMemo ist einer der am wenigsten genutzten, aber interessantesten React-Hooks. Es kann die Leistung verbessern und die Latenz verringern, insbesondere bei großen Berechnungen in Ihrer App. Wie? Jedes Mal, wenn der Status einer Komponente aktualisiert und Komponenten neu gerendert werden, wird die useMemo Hook verhindert, dass React Werte neu berechnen muss.

Sie sehen, Funktionen reagieren auf Zustandsänderungen. Das useMemo Haken übernimmt eine Funktion und gibt den Rückgabewert dieser Funktion zurück. Es speichert diesen Wert zwischen, um zusätzlichen Aufwand für das erneute Rendern zu vermeiden, und gibt ihn dann zurück, wenn sich eine der Abhängigkeiten geändert hat.

Dieser Prozess wird aufgerufen Memoisierung und es hilft, die Leistung zu steigern, indem es sich an den Wert einer früheren Anfrage erinnert, sodass er erneut verwendet werden kann, ohne all diese Berechnungen wiederholen zu müssen.

Anwendungsszenarien

Die besten Anwendungsfälle sind immer dann, wenn Sie mit umfangreichen Berechnungen arbeiten, bei denen Sie den Wert speichern und bei nachfolgenden Zustandsänderungen verwenden möchten. Es kann ein schöner Leistungsgewinn sein, aber wenn Sie es zu oft verwenden, kann es genau den gegenteiligen Effekt haben, indem Sie den Speicher Ihrer App in Beschlag nehmen.

Syntax

useMemo( () => 
  { // Code goes here },
  []
)

Beispiel

Wenn Sie auf die Schaltfläche klicken, zeigt dieses Miniprogramm an, ob eine Zahl gerade oder ungerade ist, und quadriert dann den Wert. Ich habe der Schleife viele Nullen hinzugefügt, um die Rechenleistung zu erhöhen. Es gibt den Wert in verschütteten Sekunden zurück und funktioniert aufgrund von immer noch gut useMemo Haken.

// UseMemo.js
import React, { useState, useMemo } from 'react'

function Memo() {
  const [memoOne, setMemoOne] = useState(0);
  const incrementMemoOne = () => { setMemoOne(memoOne + 1) }
  const isEven = useMemo(() => { 
    let i = 0 while (i < 2000000000) i++ return memoOne % 2 === 0
  },
  [memoOne]);
  
  const square = useMemo(()=> { 
    console.log("squared the number"); for(var i=0; i < 200000000; i++);
    return memoOne * memoOne;
  },
  [memoOne]);

  return (
    Memo One - 
    { memoOne }
    { isEven ? 'Even' : 'Odd' } { square } 
  );
}
export default Memo

Output

useMemo ist ein bisschen wie die useCallback Haken, aber der Unterschied ist das useMemo kann einen gespeicherten Wert aus einer Funktion speichern, wo useCallback speichert die gespeicherte Funktion selbst.

useCallback

Das useCallback Hook ist ein weiterer interessanter und der letzte Abschnitt war eine Art Spoiler-Alarm für das, was er tut.

Wie wir gerade gesehen haben, useCallback funktioniert wie die useMemo Haken, dass sie beide Memoization verwenden, um etwas für die spätere Verwendung zwischenzuspeichern. Während useMemo speichert die Berechnung einer Funktion als zwischengespeicherten Wert, useCallback speichert und gibt eine Funktion zurück.

Anwendungsszenarien

Like useMemo, useCallback ist eine nette Leistungsoptimierung, da es einen gespeicherten Rückruf und alle seine Abhängigkeiten ohne erneutes Rendern speichert und zurückgibt.

Syntax

const getMemoizedCallback = useCallback (
  () => { doSomething () }, []
);

Beispiel


{ useCallback, useState } from "react";
import CallbackChild from "./UseCallback-Child";
import "./App.css"

export default function App() {
  const [toggle, setToggle] = useState(false);
  const [data, setData] = useState("I am a data that would not change at every render, thanks to the useCallback");
  const returnFunction = useCallback(
    (name) => 
    { return data + name; }, [data]
  );
  return (
    onClick={() => {
      setToggle(!toggle);
    }}
    >
    {" "}

    // Click To Toggle
    { toggle && h1. Toggling me no longer affects any function } 
  ); 
}
// The Child component
import React, { useEffect } from "react";

function CallbackChild(
  { returnFunction }
) {
  useEffect(() => 
    { console.log("FUNCTION WAS CALLED"); },
    [returnFunction]);
  return { returnFunction(" Hook!") };
}
export default CallbackChild;

Output

Abschließende Gedanken

Na, bitte! Wir haben uns gerade fünf superpraktische React-Hooks angesehen, die meiner Meinung nach oft übersehen werden. Wie bei vielen Zusammenfassungen wie dieser kratzen wir nur an der Oberfläche dieser Haken. Sie haben jeweils ihre eigenen Nuancen und Überlegungen, die Sie berücksichtigen müssen, wenn Sie sie verwenden. Aber hoffentlich haben Sie eine gute Vorstellung davon, was sie sind und wann sie besser passen als ein anderer Haken, nach dem Sie vielleicht öfter greifen.

Der beste Weg, sie vollständig zu verstehen, ist durch Übung. Ich ermutige Sie daher, die Verwendung dieser Hooks in Ihrer Anwendung zum besseren Verständnis zu üben. Dazu können Sie viel mehr in die Tiefe gehen, indem Sie sich die folgenden Ressourcen ansehen:

Zeitstempel:

Mehr von CSS-Tricks