CONTATTACI

Guide per aspiranti programmatori

Programmatore che esamina react al microscopio
Lezione 13 / 41

Che cos’è lo stato di un componente in React

Lo stato di un componente in React è la rappresentazione del componente in un momento specifico del tempo, tipicamente adesso. “Adesso” inteso come il momento in cui si guarda lo stato.

Facciamo, come prima cosa, un esempio pratico; parleremo del concetto teorico nella prossima sezione.  L’esempio in questione è il più classico degli esempi in React.

Immaginiamo di voler creare un contatore.
Vogliamo due bottoni, uno che dice più (+) e uno che dice meno (-). Il contatore inizia con valore zero. Il bottone che dice + aumenta di uno il valore del contatore, il bottone che dice – diminuisce di uno il valore del contatore. Il contatore non scende mai sotto zero. Lasciamo da parte, per un attimo, le props e gli eventi, inserendo l’intera logica nel componente contatore, mentre App non farà altro che ospitarlo.

Iniziamo creando un componente che mostra solo l’interfaccia.
Possiamo inserirlo nella cartella components e chiamarlo Counter. Creiamo anche un file Counter.css relativo. Possiamo tenere l’elemento Panel, ma dobbiamo ricordarci di rimuovere il controllo che non permette a Panel di avere componenti figli che non siano Message, altrimenti ci troveremo un errore.

 

// File: src/components/Counter.jsx

import "./Counter.css";

export default function Counter() {
  return (
    <div className="Counter">
      <button>-</button>
      <span>0</span>
      <button>+</button>
    </div>
  );
}
/* File: src/components/Counter.css */

.Counter > * + * {
  margin-left: 0.5em;
}
// File: src/App.jsx

import "./App.css";
import Counter from "./components/Counter";
import Panel from "./components/Panel";

export default function App() {
  return (
    <div className="App">
      <Panel>
        <Counter />
      </Panel>
    </div>
  );
}
// File: arc/components/Panel.jsx

import "./Panel.css";

export default function Panel({ children }) {
  return <div className="Panel">{children}</div>;
}

Ragioniamo, ora, sulla struttura del counter:

  • Il numero al centro rappresenta il valore del contatore “adesso”. È il nostro stato!
  • Il bottone che dice – deve togliere uno al valore del contatore, a meno che il valore non sia zero. In altre parole, se il valore del contatore è diverso da zero, lo diminuisce di uno.
  • Il bottone che dice + deve aggiungere uno al valore del contatore.

Ecco il codice che rappresenta queste funzionalità:

 

// File: src/components/Counter.jsx

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

export default function Counter() {
  const [value, setValue] = useState(0);

  const onMinusButtonClick = () => {
    if (value !== 0) {
      setValue((value) => {
        return value - 1;
      });
    }
  };

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

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

Analizziamo il codice soprastante:

  • useState è la funzione importata da React che ci permette di creare uno stato. La funzione prende come argomento lo stato iniziale, in questo caso 0. Lo stato iniziale è il valore che ha lo stato nel momento in cui il componente viene creato. Il valore iniziale di useState può anche essere calcolato con una funzione, in questo caso passiamo una funzione callback a useState (useState(() => { /* qui calcoliamo lo stato */ })). Attenzione: quando usiamo una funzione per calcolare il valore iniziale dello stato, la funzione deve essere sincrona (i.e.: non possiamo usare async o una Promise). Per gestire stati asincroni, ci sono delle teniche che vedremo nelle prossime sezioni.
  • useState restituisce un array con due valori al suo interno. Il primo valore della coppia restituita da useState è il valore dello stato “adesso”. Il secondo valore della coppia restituita da useState è una funzione, che possiamo chiamare setter (“impostatrice”).

    La funzione setter serve a impostare il valore che lo stato avrà “dopo”, il prossimo valore. La funzione setter non restituisce nulla. Inoltre, è bene precisare che la funzione setter è una funzione di ordine superiore e gli sviluppatori di React incoraggiano l’utilizzo di una callback (così come mostrato negli esempi precedenti per incrementare o decrementare un valore)
  • Usiamo la destruttrazione per estrarre i valori della coppia restituita da useState. Avremmo potuto scrivere una cosa come const valueState = useState(0);, e poi chiamare il valore valueState[0] e la funzione setter valueState[1]. Invece, per comodità, desctrutturiamo la coppia con const [value, setValue] = useState(0);.
  • I nomi che abbiamo dato ai valori della coppia restituita da useState sono più o meno arbitrari. È convenzionale, in React, chiamare la funzione setter con set seguito dal nome dello stato (per esempio [message, setMessage], [isVisible, setIsVisible]). Abbiamo scelto value perché lo stato rappresenta il valore del contatore. Essendo all’interno del componente Counter il fatto che il valore sia “del contatore” è implicito (per cui non abbiamo scelto, per esempio, counterValue).
  • Definiamo due event listener. All’interno, chiamiamo la funzione setter con il valore che lo stato dovrà avere “dopo”, vale a dire il prossimo valore. Nel caso di onMinusButtonClick, se il valore di “adesso” è diverso da zero (cioè maggiore o uguale a zero, perché – ricordiamo – il valore non scende mai sotto zero), allora il prossimo valore è il valore di “adesso”, meno uno. Nel caso di onPlusButtonClick, il prossimo valore è sempre il valore “attuale”, più uno.

 

Immutabilità dello stato di un componente in React e callback

Ci sono due cose estremamente importanti da sapere sugli stati di React:

  1. Lo stato è immutabile. Questo vuol dire che il valore dello stato (in questo caso value) non può essere modificato direttamente: per modificarlo, utilizziamo la funzione setter. Che lo stato sia un valore primitivo – come una stringa o un numero – o che sia una struttura come un array o un oggetto, modificare direttamente il valore dello stato (per esempio con value = 42 o value++) non ha nessun effetto. Il perché lo scopriremo nelle prossime sezioni.
  2. La funzione setter può essere chiamata in due modi: passando direttamente il prossimo valore dello stato, per esempio setValue(0), oppure, come nell’esempio soprastante, passando una funzione che prende come argomento il valore dello stato “adesso” e restituisce il prossimo valore.

    Si utilizza la seconda forma quando il prossimo valore dello stato dipende da quello corrente, quando il valore corrente ci serve per calcolare il prossimo. Si utilizza la prima forma quando il valore corrente non è importante, quando il prossimo valore dello stato è costante.

Quando il calcolo del prossimo valore dello stato contiene il valore corrente, cioè quando il prossimo valore dello stato dipende da quello di “adesso”, è importante utilizzare la forma setState((currentStateValue) => { return nextStateValue; }); invece della forma setState(nextStateValue);.

Anche se il valore corrente dello stato potrebbe essere a nostra disposizione nel momento in cui chiamiamo la funzione setter, ci sono dei casi in cui questo valore potrebbe non essere aggiornato. Per evitare il problema, se il valore dello stato “adesso” ci serve per calcolare quello “dopo”, chiamiamo sempre la funzione setter passando una funzione.

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.