Ottimizzare la gestione dello stato

22 novembre 2016

La gestione dello stato in React è davvero potente, ma nasconde insidie da tenere sempre sotto controllo quando si scrivono i componenti.

React si impegna a mantenere il componente sincronizzato con il proprio stato, rispondendo alle sue variazioni, quindi meno campi sono presenti nell’oggetto, più facile sarà la manutenzione del componente durante il suo ciclo di vita nella pagina.

Per questo l’accorgimento principale è quello di semplificare il più possibile la struttura dell’oggetto che rappresenta lo stato e inserire al suo interno la quantità minima possibile di informazioni.

La normalizzazione dello stato passa da una scelta che per molti sviluppatori React rappresenta un dubbio amletico: quali dati vanno inseriti nelle proprietà e quali nello stato?

Tutto ciò che può mutare nel corso della vita del componente deve rientrare nello stato, mentre tutto ciò che rappresenta una costante può essere inserita tra le proprietà o in un campo del componente.

Stato e campi calcolati

Nel prendere queste decisioni, occorre anche fare attenzione a non inserire nello stato valori che sono dipendenti o conseguenti ad altri campi dello stato, ad esempio i campi calcolati. In questi casi, si ha uno stato “denormalizzato” e occorre assumersi anche la responsabilità di aggiornare gli eventuali campi calcolati oltre a quelli da cui questi dipendono. In caso di errore, il componente si “romperà” entrando in una condizione non congrua.

Per evitare il problema, è sufficiente inglobare la logica di calcolo all’interno di funzioni private del componente, che possono accedere allo stato e restituire l’informazione calcolata in qualsiasi momento.

Riprendendo il nostro esempio e supponendo di voler mostrare la differenza tra il conteggio iniziale e quello attuale, potremmo essere tentati di inserire il campo calcolato nello stato per poterlo visualizzare:

getInitialState: function () {
    return {
        counter: parseInt(this.props.initialCounter),
        step: parseInt(this.props.initialStep),
        left: 0
    }
},
doTick: function () {
    var newCounter = this.state.counter;
    if (newCounter <= 0)
        return;
    newCounter -= this.state.step;
    if (newCounter < 0)
        newCounter = 0;
    this.setState({
        counter: newCounter,
        left: this.props.initialCounter - newCounter
    });
}

Ora però dovremo tenerlo aggiornato anche altrove, non solo nella funzione doTick ma anche in resetCounter(), pena la visualizzazione di informazioni errate o incongruenti.

Occorre rimuovere il campo dallo stato del componente, semplificandolo di conseguenza, e creare una funzione apposita, ad esempio getDelta(), che restituisca il valore calcolato a partire dalle variabili dello stato, il quale diventa la “fonte unica di verità” (Single Source of Truth), ovvero la struttura dati che rappresenta l’unico punto da cui è possibile estrarre i dati aggiornati e garantiti come tali.

Ecco una possibile versione corretta del codice:

getDelta: function () {
    return this.props.initialCounter - this.state.counter;
},
render: function () {
    return (
        <div>
            <strong>{this.state.counter}</strong>
            &nbsp;
            <small>{this.getDelta()}</small>
            &nbsp;
            <button type="button" onClick={this.resetCounter}>Reset</button>
            <button type="button" onClick={this.speedUp}>+</button>
            <button type="button" onClick={this.speedDown}>-</button>
        </div>
    );
}

Pattern da evitare

Per individuare i pattern da evitare, vi sono alcuni indizi – i cosiddetti “come smell” – che sviluppando in React si possono riconoscere:

  • Quando si inizia ad aggiornare più campi dello stato, è probabile che alcuni siano conseguenti ad altri e possano essere quindi trasformati in funzioni e rimossi dallo stato.
  • Se un campo dello stato non viene mai aggiornato, ovviamente non deve fare parte dello stato.
  • Quando si inserisce un nuovo campo, occorre valutare se esso non fa parte (assieme ad altri campi) di un set di informazioni che possono essere espresse collettivamente con un solo valore (un enumerativo, ad esempio): se la risposta è affermativa, è più efficiente riunire i campi in un valore unico.

Benché React gestisca in modo estremamente performante l’aggiornamento della pagina, seguire questi accorgimenti nella definizione dello stato vi consentirà di mantenere compatto e semplice il codice del componente e coadiuvare React nel massimizzare le sue già ottime prestazioni.

Tutte le lezioni

1 ... 14 15 16 ... 19

Se vuoi aggiornamenti su Ottimizzare la gestione dello stato inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Ottimizzare la gestione dello stato

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy