
GUIDE PER ASPIRANTI PROGRAMMATORI
Economia dei componenti in React
In questo momento, la nostra applicazione ha due problemi: Troppo codice nel componente App. È davvero bruttina da vedere; non che il nostro CSS sia da premio, ci stiamo concentrando sui concetti di React, ma così siamo proprio in preda all’aspetto di default del browser. Come possiamo risolvere? Ci sono due elementi div, rispettivamente con…


Vuoi avviare una nuova carriera o fare un upgrade?
Trova il corso Digital & Tech più adatto a te nel nostro catalogo!
In questo momento, la nostra applicazione ha due problemi:
- Troppo codice nel componente App.
- È davvero bruttina da vedere; non che il nostro CSS sia da premio, ci stiamo concentrando sui concetti di React, ma così siamo proprio in preda all’aspetto di default del browser.
Come possiamo risolvere?
Ci sono due elementi div, rispettivamente con classe TodoList e TodoItem, che sembrano proprio chiedere di essere isolati in componenti! Facciamolo: creiamo due nuovi componenti, in src/components/TodoList e src/components/TodoItem, con i loro file CSS relativi.
/* File: src/components/TodoItem.css */ .TodoItem { display: flex; align-items: baseline; } .TodoItem input[type="checkbox"] { margin: 0 0.5em 0 0; } // File: src/components/TodoItem.jsx import "./TodoItem.css"; export default function TodoItem({ todoItem }) { return ( <div className="TodoItem"> <input type="checkbox" checked={todoItem.isDone} disabled /> <span>{todoItem.description}</span> </div> ); } /* File: src/components/TodoList.css */ .TodoList { width: 90vw; max-width: 45em; margin: 1.5em auto; } // File: src/components/TodoList.jsx import TodoItem from "./TodoItem"; import "./TodoList.css"; export default function TodoList({ todoList }) { return ( <div className="TodoList"> {todoList.map((todoItem, index, todoList) => { return <TodoItem key={todoList.length - index} todoItem={todoItem} />; })} </div> ); } // File: src/App.jsx import { useState } from "react"; import "./App.css"; import Panel from "./components/Panel"; import TodoItemForm from "./components/TodoItemForm"; import TodoList from "./components/TodoList"; export default function App() { const [todoList, setTodoList] = useState([]); const onTodoItemFormSubmit = (todoItem) => { return setTodoList((todoList) => [todoItem, ...todoList]); }; return ( <div className="App"> <TodoList todoList={todoList} /> <Panel> <TodoItemForm onSubmit={onTodoItemFormSubmit} /> </Panel> </div> ); }
Molto meglio! Adesso abbiamo un minimo di allineamento.
Notiamo come l’attributo key non è stato portato dentro il componente TodoItem ma è rimasto in TodoList. Come abbiamo detto precedentemente, key non ha a che fare con la configurazione degli elementi o componenti, ma con la gestione di liste di elementi o componenti sullo stesso livello. Inoltre, dato che key è sempre valido sia come attributo che come proprietà, potevamo assegnarlo all’elemento div come possiamo assegnarlo ora al componente TodoItem e, anche se non è considerato all’interno del nostro componente, viene gestito direttamente da React.
In ottica di componenti controller/view, abbiamo creato dei nuovi componenti view, lasciando lo stato nel componente App, che controlla il nuovo componente TodoList e, di conseguenza, (visto che TodoList non è un componente controller) anche TodoItem.
Quando isolare un componente?
Approfittiamo di questo momento per ragionare sulla domanda: quando ha senso isolare un componente?
La risposta, forse un po’ vaga, è “ogni volta che cambiamo argomento”. Con questo intendiamo che, quando ci troviamo per le mani un nuovo “pezzo” di struttura dati, possiamo decidere di assegnarne la responsabilità a un nuovo componente. La distinzione tra un argomento e un altro è chiaramente soggetta alla sensibilità di chi sta scrivendo il codice: ecco perché la risposta è così vaga!
In questo caso, a nostro parere, gli argomenti sono: l’intera applicazione, la lista delle cose da fare e il singolo elemento della lista.
Il fatto di avere ottenuto sintassi come <TodoList todoList={todoList} /> e <TodoItem todoItem={todoItem} /> dovrebbe rassicurarci sul fatto che stiamo andando nella direzione giusta.
Quello di cui abbiamo appena parlato si applica sia da un punto di vista di dati, che da un punto di vista grafico: ogni elemento dell’interfaccia grafica dovrebbe sempre riflettere un pezzo di informazione, come i tag visualizzati come etichette, o le operazioni possibili visualizzate come bottoni. Questo dipende, però, anche da chi progetta le interfacce grafiche e non sempre la relazione è così univoca.
Un’attenta progettazione degli stati, delle prop e degli eventi, così come l’attenzione all’equilibrio tra componenti controller e componenti view, dovrebbero fare la maggior parte del lavoro. La quantità di componenti che ne risulta dovrebbe essere già equilibrata. Se dovessi trovarti a lavorare con componenti molto grandi (i.e.: che contengono molto codice) i casi sono due: o staresti effettivamente descrivendo cose molto complesse, oppure parte della logica potrebbe essere spostata in componenti figli o dentro funzioni hook.
Cos’è una funzione hook? Scopriamolo nella prossima sezione!
CONTENUTI GRATUITI IN EVIDENZA
Guide per aspiranti programmatori 👨🏻🚀
Vuoi muovere i primi passi nel Digital e Tech? Abbiamo preparato alcune guide per aiutarti a orientarti negli ambiti più richiesti oggi.