React Hooks: i tagli profondi alla data intelligence di PlatoBlockchain. Ricerca verticale. Ai.

React Hooks: i tagli profondi

I ganci sono funzioni riutilizzabili. Ti permettono di usare stato e altre funzionalità (ad esempio metodi del ciclo di vita e così via) senza scrivere una classe. Le funzioni di hook ci consentono di "agganciare" il Reagire al ciclo di vita dello stato utilizzando componenti funzionali, consentendoci di manipolare lo stato dei nostri componenti funzionali senza doverli convertire in componenti di classe.

Reagire ganci introdotti nella versione 16.8 e da allora ne ha aggiunti altri. Alcuni sono più usati e popolari di altri, come useEffect, useStatee useContext ganci. Non ho dubbi sul fatto che tu abbia raggiunto quelli se lavori con React.

Ma quello che mi interessa sono gli hook React meno conosciuti. Sebbene tutti gli hook di React siano interessanti a modo loro, ce ne sono cinque che voglio davvero mostrarti perché potrebbero non apparire nel tuo lavoro quotidiano – o forse lo fanno e conoscerli ti dà alcuni superpoteri in più.

Sommario

useReducer

Il useReducer hook è uno strumento di gestione dello stato come altri hook. Nello specifico, è un'alternativa al useState gancio.

Se si utilizza il useReducer hook per cambiare due o più stati (o azioni), non dovrai manipolare quegli stati individualmente. Il gancio tiene traccia di tutti gli stati e li gestisce collettivamente. In altre parole: gestisce e ripropone i cambiamenti di stato. non mi piace il useState gancio, useReducer è più facile quando si tratta di gestire molti stati in progetti complessi.

Utilizzo Tipico

useReducer può aiutare a ridurre la complessità del lavoro con più stati. Usalo quando ti trovi a dover tenere traccia di più stati collettivamente, poiché ti consente di trattare la gestione degli stati e la logica di rendering di un componente come preoccupazioni separate.

Sintassi

useReducer accetta tre argomenti, uno dei quali è facoltativo:

  • una funzione di riduzione
  • initialState
  • an init funzione (opzionale)
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction) // in the case where you initialize with the optional 3rd argument

Esempio

L'esempio seguente è un'interfaccia che contiene un input di testo, un contatore e un pulsante. L'interazione con ogni elemento aggiorna lo stato. Nota come useReducer ci consente di definire più casi contemporaneamente anziché configurarli singolarmente.

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;

Dal codice sopra, ho notato come siamo in grado di gestire facilmente diversi stati nel file riduttore (switch-case), questo mostra il vantaggio del useReducer. Questa è la potenza che offre quando si lavora in applicazioni complesse con più stati.

useRef

Il useRef hook viene utilizzato per creare riferimenti sugli elementi per accedere al DOM. Ma più di questo, restituisce un oggetto con a .current proprietà che può essere utilizzata durante l'intero ciclo di vita di un componente, consentendo ai dati di persistere senza causare un nuovo rendering. Così la useRef il valore rimane lo stesso tra i rendering; l'aggiornamento del riferimento non attiva un nuovo rendering.

Utilizzo Tipico

Raggiungi il useRef aggancia quando vuoi:

  • Manipolare il DOM con informazioni mutevoli memorizzate.
  • Accedere alle informazioni dai componenti figlio (elementi nidificati).
  • Metti a fuoco un elemento.

È molto utile quando si archiviano dati mutabili nell'app senza causare un nuovo rendering.

Sintassi

useRef accetta solo un argomento, che è il valore iniziale.

const newRefComponent = useRef(initialValue);

Esempio

Qui ho usato il useRef ed useState hook per mostrare la quantità di volte in cui un'applicazione esegue il rendering di uno stato aggiornato durante la digitazione di un input di testo.

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;

Nota come la digitazione di ogni carattere nel campo di testo aggiorna lo stato dell'app, ma non attiva mai un rendering completo.

useImperativeHandle

Sai come un componente figlio ha accesso alle funzioni di chiamata passate a loro dal componente padre? I genitori li trasmettono tramite oggetti di scena, ma quel trasferimento è "unidirezionale", nel senso che il genitore non è in grado di chiamare una funzione che è nel bambino.

Bene, useImperativeHandle consente a un genitore di accedere alle funzioni di un componente figlio.

Come funziona?

  • Una funzione è definita nel componente figlio.
  • A ref viene aggiunto nel genitore.
  • Usiamo forwardRef, permettendo il ref che è stato definito per essere trasmesso al bambino.
  • useImperativeHandle espone le funzioni del bambino tramite il ref.

Utilizzo Tipico

useImperativeHandle funziona bene quando si desidera che un componente padre sia influenzato dalle modifiche nel figlio. Quindi, cose come una messa a fuoco modificata, l'incremento e il decremento e gli elementi sfocati possono essere situazioni in cui ti ritrovi a raggiungere questo gancio in modo che il genitore possa essere aggiornato di conseguenza.

Sintassi

useImperativeHandle (ref, createHandle, [dependencies])

Esempio

In questo esempio, abbiamo due pulsanti, uno in un componente padre e uno in un figlio. Facendo clic sul pulsante genitore si recuperano i dati dal figlio, consentendoci di manipolare il componente genitore. È impostato in modo che facendo clic sul pulsante figlio non passi nulla dal componente genitore al figlio per aiutare a illustrare come stiamo passando le cose nella direzione opposta.

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

Uscita

useMemo

useMemo è uno degli hook React meno utilizzati ma più interessanti. Può migliorare le prestazioni e ridurre la latenza, in particolare su calcoli di grandi dimensioni nella tua app. Come mai? Ogni volta che lo stato di un componente si aggiorna e si esegue nuovamente il rendering, il file useMemo hook impedisce a React di dover ricalcolare i valori.

Vedete, le funzioni rispondono ai cambiamenti di stato. Il useMemo hook prende una funzione e restituisce il valore di ritorno di quella funzione. Memorizza quel valore nella cache per evitare di spendere ulteriori sforzi per rieseguire il rendering, quindi lo restituisce quando una delle dipendenze è cambiata.

Questo processo è chiamato memoizzazione ed è ciò che aiuta a migliorare le prestazioni ricordando il valore di una richiesta precedente in modo che possa essere riutilizzato senza ripetere tutta quella matematica.

Utilizzo Tipico

I migliori casi d'uso si verificheranno ogni volta che si lavora con calcoli pesanti in cui si desidera archiviare il valore e utilizzarlo nei successivi cambiamenti di stato. Può essere una bella vittoria in termini di prestazioni, ma usarla troppo può avere l'effetto esattamente opposto occupando la memoria della tua app.

Sintassi

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

Esempio

Quando si fa clic sul pulsante, questo mini-programma indica quando un numero è pari o dispari, quindi quadra il valore. Ho aggiunto molti zeri al ciclo per aumentarne la potenza di calcolo. Restituisce il valore in secondi versati e funziona ancora bene grazie a useMemo gancio.

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

Uscita

useMemo è un po' come il useCallback gancio, ma la differenza è che useMemo può memorizzare un valore memorizzato da una funzione, dove useCallback memorizza la funzione memorizzata stessa.

useCallback

Il useCallback hook è un altro interessante e l'ultima sezione era una sorta di avviso spoiler per quello che fa.

Come abbiamo appena visto, useCallback funziona come useMemo hook in che entrambi usano la memorizzazione nella cache di qualcosa per un uso successivo. Mentre useMemo memorizza il calcolo di una funzione come valore memorizzato nella cache, useCallback memorizza e restituisce una funzione.

Utilizzo Tipico

Come useMemo, useCallback è una buona ottimizzazione delle prestazioni in quanto memorizza e restituisce un callback memorizzato e tutte le sue dipendenze senza un nuovo rendering.

Sintassi

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

Esempio


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

Uscita

Conclusioni

Eccoci! Abbiamo appena esaminato cinque ganci React super pratici che penso vengano spesso trascurati. Come con molti rastrellamenti come questo, stiamo semplicemente grattando la superficie di questi ganci. Ognuno di loro ha le proprie sfumature e considerazioni di cui tenere conto quando li usi. Ma si spera che tu abbia una bella idea di alto livello di cosa sono e quando potrebbero adattarsi meglio di un altro gancio che potresti raggiungere più spesso.

Il modo migliore per comprenderli appieno è la pratica. Quindi ti incoraggio a esercitarti nell'uso di questi hook nella tua applicazione per una migliore comprensione. Per questo, puoi approfondire molto controllando le seguenti risorse:

Timestamp:

Di più da Trucchi CSS