CONTATTACI

Guide per aspiranti programmatori

Programmatore che esamina react al microscopio
Lezione 14 / 41

Sollevare lo stato in React

Abbiamo finalmente chiuso il cerchio con props, eventi e stati. Prima di continuare a ragionare sul funzionamento di React, modifichiamo la nostra app per utilizzare tutti e tre i concetti.

L’operazione che stiamo per effettuare si chiama “sollevamento dello stato” ed è un’operazione molto comune nello sviluppo di applicazioni React.

Il concetto di base è che gli stati che vengono utilizzati da più componenti dovrebbero stare nel componente genitore che li contiene tutti, in modo che le informazioni possano viaggiare verso i figli senza essere duplicate. Una sorta di “minimo comun denominatore”, per cui il genitore comune più vicino contiene lo stato condiviso dai suoi discendenti. Per fare un esempio specifico del nostro caso, se il valore del contatore servisse non solo al componente Counter, ma ad altri componenti, non avrebbe senso creare lo stato nel componente Counter e cercare di tenerlo sincronizzato con App per passarlo ad altri componenti figli di App. Visto che le informazioni in React viaggiano solo dai genitori verso i figli, è bene che esse vivano nei componenti genitori.

Allo stesso modo, se il contatore non fosse aggiornato solo da Counter ma anche da altri componenti (per esempio, se App avesse un altro componente figlio che contiene un bottone per riportare il valore del contatore a zero), sarebbe di nuovo meglio tenere lo stato che rappresenta il valore del contatore all’interno di App e non all’interno di Counter.

Per effettuare questa operazione di sollevamento dello stato, possiamo sfruttare props ed eventi.

Possiamo descrivere la situazione corrente in questo modo: “il componente Counter contiene lo stato che rappresenta il suo valore. Quando i bottoni all’interno di Counter vengono cliccati, Counter aggiorna il suo stato”.

Possiamo, invece, descrivere la situazione che vogliamo ottenere in questo modo: “il componente App contiene lo stato che rappresenta il valore del contatore. Il componente App passa l’informazione che rappresenta il valore del contatore al componente Counter. Quando i bottoni all’interno di Counter vengono cliccati, Counter lancia un evento, che viene ascoltato da App e notifica App del nuovo valore del contatore. Quando App riceve un evento del genere, App aggiorna il suo stato interno. Questo perchè, se lasciassimo il cambio di stato all’interno del contatore e avessimo più di un counter, accadrebbe che ogni singolo counter verrebbe gestito all’unisono e non in maniera indipendente.

Cominciamo con la modifica di Counter:

 

import "./Counter.css";

export default function Counter({ value, onValueChange }) {
  const onMinusButtonClick = () => {
    if (value !== 0) {
      onValueChange(value - 1);
    }
  };

  const onPlusButtonClick = () => {
    onValueChange(value + 1);
  };

  return (
    <div className="Counter">
      <button onClick={onMinusButtonClick}>-</button>
      <span>{value}</span>
      <button onClick={onPlusButtonClick}>+</button>
    </div>
  );
}

Come nel caso precedente, all’interno di Counter chiamiamo il valore del contatore value. Questa volta, però, ci aspettiamo di riceverlo come proprietà.

Non abbiamo più una funzione setter (setValue) perché, dal punto di vista di Counter, non importa cosa farà il suo componente genitore con il prossimo valore di value. Noi sappiamo che Counter riceverà una funzione onValueChange che corrisponde a una funzione setter, ma Counter non lo sa, né gli interessa. Il compito di Counter è solo quello di notificare che value ha un nuovo valore, e qual è il nuovo valore.

Passiamo ad App:

 

import { useState } from "react";
import "./App.css";
import Counter from "./components/Counter";
import Panel from "./components/Panel";

export default function App() {
  const [counterValue, setCounterValue] = useState(0);

  const onCounterValueChange = (newCounterValue) => {
    setCounterValue(newCounterValue);
  };

  return (
    <div className="App">
      <Panel>
        <Counter value={counterValue} onValueChange={onCounterValueChange} />
      </Panel>
    </div>
  );
}

La cosa più importante da notare, qui, è la nomenclatura. Mentre all’interno di Counter parliamo di value e onValueChange, all’interno di App parliamo di counterValue, setCounterValue e onCounterValueChange. In App, value sarebbe un nome troppo generico: valore di cosa? Se App avesse cento componenti figli, nel momento in cui qualcuno dovesse leggere il nostro codice, dovrebbe poter capire di cosa stiamo parlando.

Il resto dovrebbe essere abbastanza auto-esplicativo, ma importante perché questo è il primo caso in cui usiamo props, eventi e stati tutti insieme. Il valore del contatore viene passato a Counter tramite props, il componente App viene notificato da Counter quando il valore del contatore cambia, e App mantiene lo stato del componente “adesso”.

 

Componenti view e componenti controller in React

Possiamo definire App un componente controller (“controllore”) e Counter un componente view (“vista”). 

Counter è un componente view perché il suo compito è quello di visualizzare uno stato che riceve dall’esterno e notificare i cambiamenti di questo stato. 

App è un componente controller perché il suo compito è di gestire uno stato che viene visualizzato da un altro componente.

La progettazione di componenti controller e componenti view in React è molto importante.

Da una parte, i componenti view sono più facilmente riutilizzabili, soprattutto quando non visualizzano un’informazione in particolare ma un tipo di informazione. Possiamo immaginare un componente view creato per rappresentare tutti gli utenti, tutti gli elementi di una lista, o tutti i numeri: finché la struttura dell’informazione resta uguale, dato che il componente view non gestisce uno stato ma lo visualizza soltanto e – a volte, non per forza – notifica i suoi cambiamenti, possiamo riutilizzarlo.

Dall’altra parte, i componenti controller sono il cervello della nostra applicazione, ciò che la rende effettivamente utile a qualcosa. Senza componenti controller, avremmo una bella interfaccia grafica che non combina niente.

Il segreto di un’applicazione React ben fatta è un equo bilanciamento di componenti view e componenti controller. Concentrare troppa logica in un unico componente controller rischia di rendere l’applicazione troppo complicata, ma frammentare la logica in un milione di piccoli componenti controller, diminuendo il numero di componenti view, rischia di rendere i componenti troppo specifici, quindi difficili da riutilizzare. Il resto di questa guida sarà concentrato sulla gestione di questo delicato equilibrio.

Contattaci senza impegno per informazioni sul corso

Pagamento rateale

Valore della rata: A PARTIRE DA 115 €/mese.

Esempio di finanziamento 

Importo finanziato: € 2440 in 24 rate da € 115 – TAN fisso 9,55% TAEG 12,57% – importo totale del credito € 2841.

Il costo totale del credito comprende: interessi calcolati al TAN indicato, oneri fiscali (imposta di bollo sul contratto 16,00 euro*) addebitati sulla prima rata, costo mensile di gestione pratica € 3,90, spesa di istruttoria € 0,00, spesa per invio rendicontazione periodica cartacea € 0,98 (o spesa per invio rendicontazione periodica cartacea € 0,00), imposta di bollo su rendicontazione periodica € 0,00. Modalità di rimborso obbligatoria: addebito diretto su c/c. La scadenza delle rate è determinata dal giorno della liquidazione del contratto; la data di scadenza delle rate è prevista il giorno 15 del mese. L’importo di ciascuna rata comprende una quota di capitale crescente e interessi decrescente secondo un piano di ammortamento “alla francese”. Offerta valida dal 01/01/2024 al 31/12/2024.

Messaggio pubblicitario con finalità promozionale. Per le informazioni precontrattuali richiedere sul punto vendita il documento “Informazioni europee di base sul credito ai consumatori” (SECCI) e copia del testo contrattuale. Salvo approvazione di Sella Personal Credit S.p.A. Aulab S.r.l. opera quale intermediario del credito NON in esclusiva.

*In fase di richiesta del finanziamento verrà proposta la facoltà di selezionare, in alternativa all’imposta di bollo sul contratto di 16,00 euro, l’imposta sostitutiva, pari allo 0,25% dell’importo finanziato.

Pagamento rateale

Valore della rata: A PARTIRE DA 210 €/mese.

Esempio di finanziamento  

Importo finanziato: € 4500 in 24 rate da € 210,03 – TAN fisso 9,68% TAEG 11,97% – importo totale del credito € 5146,55.

Il costo totale del credito comprende: interessi calcolati al TAN indicato, oneri fiscali (imposta di bollo sul contratto 16,00 euro*) addebitati sulla prima rata, costo mensile di gestione pratica € 3,90, spesa di istruttoria € 0,00, spesa per invio rendicontazione periodica cartacea € 0,98 (o spesa per invio rendicontazione periodica cartacea € 0,00), imposta di bollo su rendicontazione periodica € 0,00. Modalità di rimborso obbligatoria: addebito diretto su c/c. La scadenza delle rate è determinata dal giorno della liquidazione del contratto; la data di scadenza delle rate è prevista il giorno 15 del mese. L’importo di ciascuna rata comprende una quota di capitale crescente e interessi decrescente secondo un piano di ammortamento “alla francese”. Offerta valida dal 01/01/2024 al 31/12/2024.

Messaggio pubblicitario con finalità promozionale. Per le informazioni precontrattuali richiedere sul punto vendita il documento “Informazioni europee di base sul credito ai consumatori” (SECCI) e copia del testo contrattuale. Salvo approvazione di Sella Personal Credit S.p.A. Aulab S.r.l. opera quale intermediario del credito NON in esclusiva.

* In fase di richiesta del finanziamento verrà proposta la facoltà di selezionare, in alternativa all’imposta di bollo sul contratto di 16,00 euro, l’imposta sostitutiva, pari allo 0,25% dell’importo finanziato.

Contattaci senza impegno per informazioni sul corso

Scopriamo insieme se i nostri corsi fanno per te. Compila il form e aspetta la chiamata di uno dei nostri consulenti.