React
Hooks
Desenvolvimento
JavaScript
React19

Esplorando gli hook React e le innovazioni React 19

Esplorando gli hook React e le innovazioni React 19

Gli hook hanno rivoluzionato lo sviluppo di React consentendo ai componenti funzionali di gestire in modo elegante lo stato, gli effetti collaterali e la logica complessa. Con React 19 sono stati introdotti nuovi hook per snellire ulteriormente il flusso di lavoro. In questo articolo esploreremo gli hook classici, gli hook avanzati e le novità della versione 19 con esempi pratici.


Hook di reazione di base

useState: gestione semplice dello stato

Gestisce gli stati locali nei componenti funzionali. Ideale per valori che cambiano nel tempo.

Esempio: contatore interattivo

importa {useState} da 'react';

funzione Contatore() { const [conteggio, setCount] = useState(0);

ritorno (

Hai fatto clic {count} volte

<pulsante onClick={() => setCount(count + 1)}> Incremento
); }


useEffect: effetti collaterali

Esegue il codice dopo il rendering, come chiamate API o manipolazione DOM.

Esempio: recupero di dati da un'API

import {useState, useEffect} da 'react';

funzione Elenco Utenti() { const [utenti, setUsers] = useState([]);

useEffect(() => { fetch('https://api.example.com/users') .then(risposta => risposta.json()) .then(dati => setUsers(dati)); }, []); // Esegui solo una volta

ritorno (

    {utenti.map(utente => (
  • {utente.nome}
  • ))}
); }


useContext: condivisione dello stato globale

Accede ai valori di contesto senza perforazione dell'elica.

Esempio: tema scuro/chiaro

import {creaContext, useContext, useState} da 'react';

const ThemeContext = createContext();

funzione App() { const [tema, setTheme] = useState('light');

ritorno ( <ThemeContext.Provider valore=> </ThemeContext.Provider> ); }

funzione Barra degli strumenti() { const { tema, setTheme } = useContext(ThemeContext);

ritorno ( <pulsante onClick={() => setTheme(tema === 'chiaro' ? 'scuro' : 'chiaro')}> Passa al tema {tema === 'luce' ? 'scuro': 'chiaro'} ); }


useRef: riferimenti mutabili

Memorizza i valori che persistono tra i rendering senza causare nuovi rendering.

Esempio: focalizzazione sull'input

importa { useRef } da 'react';

funzione InserimentoTesto() { const inputRef = useRef(null);

const focusInput = () => { inputRef.current.focus(); };

ritorno (

); }


Ganci avanzati e personalizzati

useReducer: Stato complesso

Gestisce gli stati con una logica più elaborata, simile a Redux.

Esempio: Elenco attività

import { useReducer } da 'react';

funzione todosReducer(stato, azione) { interruttore (azione.tipo) { caso 'ADD_TODO': return [...state, {testo: azione.testo, completato: false }]; caso "TOGGLE_TODO": return state.map((da fare, indice) => indice === azione.indice ? { ...todo, completato: !todo.completed } : cosa da fare ); predefinito: stato di restituzione; } }

funzione TodoApp() { const [todos, dispatch] = useReducer(todosReducer, []);

const handleSubmit = (e) => { e.preventDefault(); dispatch({ tipo: 'ADD_TODO', testo: e.target.elements.todo.value }); e.target.reset(); };

ritorno (

{todos.map((da fare, indice) => ( < chiave={indice} onClick={() => spedizione({ tipo: 'TOGGLE_TODO', indice })} style={ textDecoration: todo.completed ? 'line-through': 'nessuno' } > {da fare.testo}
))} ); }


useMemo e useCallback: ottimizzazione delle prestazioni

  • useMemo: Memorizza i valori calcolati.
  • useCallback: Memorizza le funzioni.

Esempio: calcolo pesante

importa {useMemo, useState} da 'react';

funzioneComponente Costoso({ elenco }) { const sortedList = useMemo(() => { console.log('Elenco ordini...'); return [...elenco].sort(); }, [lista]);

return

{sortedList.join(', ')}
; }


Hook personalizzati: riutilizzo della logica

Esempio: useFetch per richieste HTTP

import {useState, useEffect} da 'react';

funzione useFetch(url) { const [dati, setData] = useState(null); const [caricamento, setLoading] = useState(true);

useEffect(() => { recuperare(URL) .then(res => res.json()) .then(dati => { setData(data); setLoading(falso); }); }, [URL]);

return {dati, caricamento}; }

// Utilizzo nel componente: funzione ProfiloUtente({ ID utente }) { const {dati: utente, caricamento} = useFetch(https://api.example.com/users/${userId});

if (caricamento in corso) return

Caricamento in corso...
; return
{nome.utente}
; }


Nuovi ganci React 19

useOptimistic: Aggiornamenti ottimistici

Aggiorna l'interfaccia utente prima del commit del server, eseguendo il rollback in caso di errore.

Esempio: aggiunta di commenti ottimistici

importa {useOptimistic} da 'react';

funzione CommentForm({ onSubmit }) { const [optimisticComments, addOptimisticComment] = useOptimistic( [], (stato, nuovoCommento) => [...stato, {testo: nuovoCommento, invio: true }] );

const handleSubmit = asincrono (e) => { e.preventDefault(); const formData = new FormData(e.target); const commento = formData.get('commento');

addOptimisticComment(commento);

prova {
  attendi l'invio (commento);
} cattura (errore) {
  // Ripristina l'interfaccia utente se la richiesta fallisce
}

};

ritorno (

{ottimisticiCommenti.map((commento, indice) => ( <div style=> {commento.testo}
))} ); }


useResource: integrazione con Suspense

Gestisce i dati asincroni in modo dichiarativo.

Esempio: caricamento dati con fallback

import { useResource, Suspense } da 'react';

funzione fetchUtente(id) { // Restituisce una promessa }

funzione ProfiloUtente({ ID utente }) { const userResource = useResource(() => fetchUser(userId));

return

{userResource.read().name}
; }

// Utilizzo nel componente principale: <Suspense fallback={

Caricamento utente...
}> <IDutenteProfiloUtente={1} />


useEventListener: ascoltatori di eventi semplificati

Gestisce i listener di eventi in modo pulito.

Esempio: dimensione della finestra di monitoraggio

importa { useEventListener } da 'react';

funzione Dimensione Finestra() { const [size, setSize] = useState({ larghezza: window.innerWidth, altezza: window.innerHeight });

useEventListener('ridimensiona', () => { setSize({ larghezza: finestra.innerWidth, altezza: finestra.innerHeight }); });

return

Dimensione della finestra: {size.width}x{size.height}
; }


useMediaQuery: design reattivo

Reagisce ai cambiamenti nelle query multimediali.

Esempio: tema scuro con preferenza di sistema

importa {useMediaQuery} da 'react';

funzione DarkModeToggle() { const prefersDark = useMediaQuery('(preferisce-schema-colori: scuro)'); const [èScuro, setIsScuro] = useState(preferisceScuro);

// Aggiorna il tema del sito qui...

ritorno ( <pulsante onClick={() => setIsDark(!isDark)}> {è scuro? 'Disabilita modalità oscura': 'Abilita modalità oscura'} ); }


useErrorBoundary: gestione elegante degli errori

Rileva gli errori nei componenti figlio.

Esempio: soglia di errore personalizzata

import { useErrorBoundary } da 'react';

funzione Componente incline all'errore() { const { ErrorBoundary, didCatch, errore } = useErrorBoundary();

restituire didCatch ? (

Si è verificato un errore: {error.message}
): ( ); }


Conclusione

Gli hook React continuano ad evolversi, offrendo strumenti potenti per semplificare lo sviluppo. Con React 19, funzionalità come useOptimistic e useResource migliorano l'esperienza dell'utente gestendo operazioni asincrone in modo fluido, mentre hook come useMediaQuery e useEventListener semplificano la creazione di interfacce adattive.

Padroneggiando questi hook, da quelli di base a quelli più recenti, sarai in grado di creare applicazioni più robuste, performanti e di più facile manutenzione. Prova a integrare queste tecniche nei tuoi progetti e guarda come trasformano il tuo flusso di lavoro! 🚀

Leggi anche