La creazione degli stati a livello globale può rallentare le prestazioni dell'app. Scopri come creare e utilizzare in modo efficace gli stati nella tua applicazione React.

Se hai scritto molto codice React, è probabile che tu abbia utilizzato state in modo errato. Un errore comune che fanno molti sviluppatori React è memorizzare gli stati a livello globale nell'applicazione, invece di memorizzarli nei componenti in cui vengono utilizzati.

Scopri come puoi eseguire il refactoring del tuo codice per utilizzare lo stato locale e perché farlo è sempre una buona idea.

Esempio base di stato in React

Ecco molto semplice applicazione contatore che esemplifica come lo stato viene tipicamente gestito in React:

importare {useState} da'reagire'
importare {Contatore} da'contatore'

funzioneApp(){
cost [count, setCount] = useState(0)
ritorno<Contatorecontare={contare}setCount={setCount} />
}

esportarepredefinito App

Nelle righe 1 e 2, si importa il file usaStato() hook per creare lo stato e il file Contatore componente. Tu definisci il

instagram viewer
contare stato e setCount metodo per l'aggiornamento dello stato. Quindi passi entrambi al Contatore componente.

IL Contatore componente quindi esegue il rendering del file contare e chiamate setCount per incrementare e decrementare il conteggio.

funzioneContatore({conteggio, impostaconteggio}) {
ritorno (

Non hai definito il contare variabile e setCount funzione localmente all'interno del Contatore componente. Piuttosto, l'hai passato dal componente genitore (App). In altre parole, stai usando uno stato globale.

Il problema con gli Stati globali

Il problema con l'utilizzo di uno stato globale è che stai memorizzando lo stato in un componente genitore (o genitore di un genitore) e poi tramandandolo come oggetti di scena al componente in cui tale stato è effettivamente necessario.

A volte questo va bene quando hai uno stato condiviso tra molti componenti. Ma in questo caso, nessun altro componente si preoccupa del contare stato ad eccezione del Contatore componente. Pertanto, è meglio spostare lo stato in Contatore componente in cui è effettivamente utilizzato.

Spostamento dello stato nel componente figlio

Quando sposti lo stato in Contatore componente, sarebbe simile a questo:

importare {useState} da'reagire'

funzioneContatore() {
cost [count, setCount] = useState(0)
ritorno (


Poi dentro il tuo App componente, non devi passare nulla al Contatore componente:

// importa
funzioneApp(){
ritorno<Contatore />
}

Il contatore funzionerà esattamente come prima, ma la grande differenza è che tutti i tuoi stati sono localmente all'interno di questo Contatore componente. Quindi, se hai bisogno di avere un altro contatore sulla home page, allora avresti due contatori indipendenti. Ogni contatore è autonomo e si prende cura di tutto il proprio stato.

Gestione dello stato in applicazioni più complesse

Un'altra situazione in cui useresti uno stato globale è con i moduli. IL App componente sottostante passa i dati del modulo (e-mail e password) e il metodo setter al file LoginModulo componente.

importare { usaStato } da"reagire";
importare {Modulo di accesso} da"./Modulo di accesso";

funzioneApp() {
cost [formData, setFormData] = useState({
e-mail: "",
parola d'ordine: "",
});

funzioneupdateFormData(newDati) {
setFormData((prec) => {
ritorno { ...prev, ...newData };
});
}

funzioneonSubmit() {
consolare.log (moduloDati);
}

ritorno (
dati={formDati}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

IL LoginModulo componente prende le informazioni di accesso e lo rende. Quando invii il modulo, chiama il file updateData funzione che viene anche trasmessa dal componente genitore.

funzioneLoginModulo({ onSubmit, dati, updateData }) {
funzionehandleSubmit(e) {
e.preventDefault();
onSubmit();
}

ritorno (


Piuttosto che gestire lo stato sul componente padre, è meglio spostare lo stato in LoginForm.js, che è dove utilizzerai il codice. In questo modo ogni componente diventa autonomo e non dipende da un altro componente (cioè il genitore) per i dati. Ecco la versione modificata del LoginModulo:

importare { usoRif } da"reagire";

funzioneLoginModulo({ onSubmit }) {
cost emailRef = useRef();
cost passwordRef = useRef();

funzionehandleSubmit(e) {
e.preventDefault();
onSubmit({
e-mail: emailRef.current.value,
password: passwordRef.current.value,
});
}

ritorno (


Qui puoi associare l'input a una variabile usando rif attributi e il usoRif React hook, piuttosto che passare direttamente i metodi di aggiornamento. Questo ti aiuta a rimuovere il codice dettagliato e ottimizzare le prestazioni del modulo utilizzando l'hook useRef.

Nel componente principale (App.js), puoi rimuovere sia lo stato globale che aggiornaFormData() metodo perché non ne hai più bisogno. L'unica funzione rimasta è onSubmit(), che invochi dall'interno del file LoginModulo componente per registrare i dettagli di accesso sulla console.

funzioneApp() {
funzioneonSubmit(formData) {
consolare.log (moduloDati);
}

ritorno (
dati={formDati}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

Non solo hai reso il tuo stato il più locale possibile, ma hai effettivamente rimosso la necessità di qualsiasi stato (e hai usato rif Invece). Quindi il tuo App componente è diventato significativamente più semplice (avendo solo una funzione).

Tuo LoginModulo anche il componente è diventato più semplice perché non dovevi preoccuparti di aggiornare lo stato. Piuttosto, tieni traccia di due rif, e basta.

Gestione dello stato condiviso

C'è un problema con l'approccio di cercare di rendere lo stato il più locale possibile. Ti imbattevi spesso in scenari in cui il componente padre non utilizza lo stato, ma lo passa a più componenti.

Un esempio è avere a TodoContenitore componente padre con due componenti figlio: Lista di cose da fare E TodoCount.

funzioneTodoContenitore() {
cost [todos, setTodos] = useState([])

ritorno (
<>


</>
)
}

Entrambi questi componenti figlio richiedono l'estensione tutti stato, così TodoContenitore lo passa a entrambi. In scenari come questi, devi rendere lo stato il più locale possibile. Nell'esempio sopra, inserendolo all'interno del file TodosContenitore è il più locale possibile.

Se dovessi mettere questo stato nel tuo App componente, non sarebbe il più locale possibile perché non è il genitore più vicino ai due componenti che necessitano dei dati.

Per applicazioni di grandi dimensioni, gestire lo stato solo con il file usaStato() gancio può rivelarsi difficile. In tali casi, potrebbe essere necessario optare per il Reagisci all'API del contesto O Reagisci Redux gestire efficacemente lo Stato.

Ulteriori informazioni sugli hook React

Gli hook costituiscono la base di React. Usando gli hook in React, puoi evitare di scrivere codice lungo che altrimenti userebbe le classi. L'hook useState() è senza dubbio l'hook React più comunemente usato, ma ce ne sono molti altri come useEffect(), useRef() e useContext().

Se stai cercando di diventare esperto nello sviluppo di applicazioni con React, devi sapere come utilizzare questi hook nella tua applicazione.