React Hooks: The Deep Cuts PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

React Hooks: The Deep Cuts

Krokar är återanvändbara funktioner. De låter dig använda tillstånd och andra funktioner (t.ex. livscykelmetoder och så vidare) utan att skriva en klass. Krokfunktioner låter oss "haka in" i Reaktionstillstånds livscykel använder funktionella komponenter, vilket gör att vi kan manipulera tillståndet för våra funktionella komponenter utan att behöva konvertera dem till klasskomponenter.

Reagera införda krokar tillbaka i version 16.8 och har lagt till fler sedan dess. Vissa är mer använda och populära än andra, typ useEffect, useStateoch useContext krokar. Jag tvivlar inte på att du har nått dem om du arbetar med React.

Men det jag är intresserad av är de mindre kända React-hakarna. Även om alla React-krokar är intressanta på sitt eget sätt, finns det fem av dem som jag verkligen vill visa dig eftersom de kanske inte dyker upp i ditt dagliga arbete – eller så kanske de gör det och att känna till dem ger dig några extra superkrafter.

Innehållsförteckning

useReducer

Smakämnen useReducer hook är ett tillståndshanteringsverktyg som andra krokar. Specifikt är det ett alternativ till useState krok.

Om du använder useReducer krok för att ändra två eller flera tillstånd (eller åtgärder), behöver du inte manipulera dessa tillstånd individuellt. Kroken håller reda på alla stater och hanterar dem kollektivt. Med andra ord: den hanterar och återger tillståndsförändringar. till skillnad från useState krok, useReducer är lättare när det gäller att hantera många stater i komplexa projekt.

Användningsfall

useReducer kan hjälpa till att minska komplexiteten i att arbeta med flera tillstånd. Använd det när du märker att du behöver spåra flera tillstånd kollektivt, eftersom det låter dig behandla tillståndshantering och renderingslogiken för en komponent som separata problem.

syntax

useReducer accepterar tre argument, varav ett är valfritt:

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

Exempelvis

Följande exempel är ett gränssnitt som innehåller en textinmatning, räknare och knapp. Att interagera med varje element uppdaterar tillståndet. Lägg märke till hur useReducer tillåter oss att definiera flera fall samtidigt istället för att ställa in dem individuellt.

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;

Från koden ovan märkte vi hur vi enkelt kan hantera flera stater i Reducer (switch-case), visar detta fördelen med useReducer. Detta är kraften det ger när man arbetar i komplexa applikationer med flera tillstånd.

useRef

Smakämnen useRef hook används för att skapa refs på element för att komma åt DOM. Men mer än så returnerar den ett objekt med en .current egenskap som kan användas under en komponents hela livscykel, vilket gör att data kan finnas kvar utan att orsaka omrendering. Så, den useRef värdet förblir detsamma mellan renderingarna; uppdatering av referensen utlöser inte en omrendering.

Användningsfall

Nå för useRef haka på när du vill:

  • Manipulera DOM med lagrad föränderlig information.
  • Få åtkomst till information från underordnade komponenter (kapslade element).
  • Sätt fokus på ett element.

Det är mest användbart när du lagrar muterbar data i din app utan att orsaka omrendering.

syntax

useRef accepterar bara ett argument, vilket är ursprungligt värde.

const newRefComponent = useRef(initialValue);

Exempelvis

Här använde jag useRef och useState krok för att visa hur många gånger ett program återger ett uppdaterat tillstånd när du skriver in en textinmatning.

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;

Lägg märke till hur att skriva varje tecken i textfältet uppdaterar appens tillstånd, men aldrig utlöser en fullständig omrendering.

useImperativeHandle

Vet du hur en underordnad komponent har tillgång till anropsfunktioner som skickas till dem från den överordnade komponenten? Föräldrar skickar dem vidare via rekvisita, men den överföringen är "enkelriktad" i den meningen att föräldern inte kan anropa en funktion som finns i barnet.

Väl, useImperativeHandle gör det möjligt för en förälder att komma åt en barnkomponents funktioner.

Hur fungerar det?

  • En funktion definieras i den underordnade komponenten.
  • A ref läggs till i föräldern.
  • Vi använder forwardRef, tillåter ref som definierades för att överföras till barnet.
  • useImperativeHandle exponerar barnets funktioner via ref.

Användningsfall

useImperativeHandle fungerar bra när man vill att en föräldrakomponent ska påverkas av förändringar hos barnet. Så saker som ett ändrat fokus, ökande och minskande och suddiga element kan vara situationer där du hittar dig själv att sträcka dig efter den här kroken så att föräldern kan uppdateras därefter.

syntax

useImperativeHandle (ref, createHandle, [dependencies])

Exempelvis

I det här exemplet har vi två knappar, en som finns i en överordnad komponent och en som är i en underordnad komponent. Genom att klicka på föräldraknappen hämtas data från barnet, vilket gör att vi kan manipulera föräldrakomponenten. Den är inställd så att ett klick på barnknappen inte skickar någonting från föräldrakomponenten till barnet för att illustrera hur vi skickar saker i motsatt riktning.

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

Produktion

useMemo

useMemo är en av de minst använda men mest intressanta React-krokarna. Det kan förbättra prestandan och minska latensen, särskilt vid stora beräkningar i din app. Hur så? Varje gång en komponents tillstånd uppdateras och komponenter återrenderas, visas useMemo krok hindrar React från att behöva räkna om värden.

Du ser, funktioner svarar på tillståndsändringar. De useMemo krok tar en funktion och returnerar returvärdet för den funktionen. Den cachar det värdet för att förhindra att ytterligare ansträngning görs om det, och returnerar det sedan när ett av beroenden har ändrats.

Denna process kallas memoisation och det är det som hjälper till att öka prestandan genom att komma ihåg värdet från en tidigare begäran så att den kan användas igen utan att behöva upprepa all den matematiken.

Användningsfall

De bästa användningsfallen kommer att vara varje gång du arbetar med tunga beräkningar där du vill lagra värdet och använda det vid efterföljande tillståndsändringar. Det kan vara en trevlig prestationsvinst, men om du använder den för mycket kan det få raka motsatta effekter genom att appens minne försämras.

syntax

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

Exempelvis

När du klickar på knappen indikerar detta miniprogram när ett tal är jämnt eller udda och kvadrerar sedan värdet. Jag la till massor av nollor i slingan för att öka dess beräkningskraft. Det returnerar värdet i utspillda sekunder och fungerar fortfarande bra på grund av useMemo krok.

// 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

Produktion

useMemo är lite som useCallback krok, men skillnaden är den useMemo kan lagra ett memorerat värde från en funktion, där useCallback lagrar den lagrade funktionen själv.

useCallback

Smakämnen useCallback Hook är en annan intressant och det sista avsnittet var en slags spoilervarning för vad den gör.

Som vi nyss såg, useCallback fungerar som useMemo haka på att de båda använder memoization för att cache något för senare användning. Medan useMemo lagrar en funktions beräkning som ett cachat värde, useCallback lagrar och returnerar en funktion.

Användningsfall

Tycka om useMemo, useCallback är en trevlig prestandaoptimering genom att den lagrar och returnerar en memoiserad återuppringning och alla dess beroenden utan omrendering.

syntax

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

Exempelvis


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

Produktion

Avslutande tankar

Där går vi! Vi tittade precis på fem superhändiga React-krokar som jag tror ofta förbises. Som med många roundups som denna, skrapar vi bara på ytan av dessa krokar. De har var och en sina egna nyanser och överväganden att ta hänsyn till när du använder dem. Men förhoppningsvis har du en bra uppfattning på hög nivå om vad de är och när de kanske passar bättre än en annan krok du kanske sträcker dig efter oftare.

Det bästa sättet att helt förstå dem är genom övning. Så jag uppmuntrar dig att träna på att använda dessa krokar i din ansökan för bättre förståelse. För det kan du bli mycket mer på djupet genom att kolla in följande resurser:

Tidsstämpel:

Mer från CSS-tricks