Reagire useContext con "setState"
Di recente ho iniziato a utilizzare Context React Api con useContext Hook. Ho osservato che quando abbiamo una variabile di stato, ad esempio const someState = useState(state, setState), alcuni sviluppatori passano setSate direttamente nei valori del provider e quindi lo chiamano nei componenti figli. È una buona pratica?
Quando non usi il contesto devi creare un gestore per "accedere" a setState in un componente figlio. Sto ancora utilizzando le funzioni del gestore e le passo ai valori del provider, per importarle dal contesto nei bambini.
Passare setState nel contesto è una buona pratica? Ho ancora dei dubbi poiché normalmente non puoi passare setState direttamente in un componente. C'è qualche differenza nelle prestazioni o altri inconvenienti che dovrei prendere in considerazione?
Grazie.
Risposte
Se ho capito bene la differenza è che in un modo lo stato è impostato dal componente genitore e nell'altro lo stato è impostato dal componente figlio. A volte le persone lo fanno in questo modo per evitare il rendering in loop con la modifica dello stato. Non dovrebbero esserci inconvenienti, ma l'uso delle funzioni di gestione è il modo normale di procedere.
Modifica: in realtà penso di averti sbagliato, ma non ne sono sicuro. La mia risposta è valida per il caso se scrivi il tuo provider che ha uno stato. Se usi solo un provider predefinito che fornisce un setter, sarei d'accordo con la risposta di Amel.
Personalmente non lo farei, ma è più un'opinione. Tuttavia, come sempre, dipende molto dall'obiettivo che vuoi raggiungere.
Un aspetto positivo di farlo è che i setter di stato forniti da useState rimangono sempre gli stessi per ogni nuovo rendering. Se passi un valore personalizzato, dovresti evitare che cambi troppo spesso perché ogni componente che ascolta la modifica usando useContext verrebbe nuovamente visualizzato.
Preferirei comunque passare un oggetto personalizzato (ad esempio proveniente da un useMemo per evitare inutili ripetizioni) con un callback per impostare lo stato. È più facile estendere se vuoi fornire più cose in futuro.
Qualcosa del genere (esempio molto semplicistico, che ovviamente non ha senso in questo modo, è solo per la comprensione):
function MyProvider({children}) {
const [state, setState] = useState(0);
const provided = useMemo(() => ({
value: state,
setValue: (value) => setState(value)
}, [value]);
return <MyContext.Provider value={provided}>{children}</MyContext.Provider>;
}
Sarebbe più semplice estendere senza modificare il codice ovunque venga utilizzato il contesto. Tuttavia, continuo a pensare che non ci sia niente di particolarmente negativo nel passare solo il palleggiatore, se è quello che vuoi ottenere.