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 dieref
die definiert wurde, um an das Kind weitergegeben zu werden. useImperativeHandle
macht die Funktionen des Kindes über die verfügbarref
.
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: