Ricerca…


Stato di base

Lo stato nei componenti React è essenziale per gestire e comunicare i dati nella tua applicazione. È rappresentato come oggetto JavaScript e ha un ambito a livello di componente , può essere considerato come i dati privati ​​del componente.

Nell'esempio seguente stiamo definendo alcuni stati iniziali nella funzione di constructor del nostro componente e ne facciamo uso nella funzione di render .

class ExampleComponent extends React.Component {
  constructor(props){
    super(props);

    // Set-up our initial state
    this.state = {
      greeting: 'Hiya Buddy!'
    };
  }

  render() {
    // We can access the greeting property through this.state
    return(
      <div>{this.state.greeting}</div>
    );
  }
}

setState ()

Il modo principale con cui si effettuano gli aggiornamenti dell'interfaccia utente alle applicazioni React è tramite una chiamata alla funzione setState() . Questa funzione eseguirà un'unione superficiale tra il nuovo stato che fornisci e lo stato precedente e attiverà un re-rendering del tuo componente e di tutti i decedenti.

parametri

  1. updater : può essere un oggetto con un numero di coppie chiave-valore che devono essere unite nello stato o una funzione che restituisce tale oggetto.
  2. callback (optional) : una funzione che verrà eseguita dopo che setState() è stato eseguito con successo. A causa del fatto che le chiamate a setState() non sono garantite da React per essere atomiche, a volte può essere utile se si desidera eseguire qualche azione dopo che si è setState() che setState() è stato eseguito correttamente.

Uso:

Il metodo setState accetta un argomento updater che può essere sia un oggetto con un numero di coppie chiave-valore che devono essere unite nello stato, sia una funzione che restituisce tale oggetto calcolato da prevState e props .

Usando setState() con un oggetto come programma di updater

//
// An example ES6 style component, updating the state on a simple button click.
// Also demonstrates where the state can be set directly and where setState should be used.
//
class Greeting extends React.Component {
    constructor(props) {
        super(props);
        this.click = this.click.bind(this);
        // Set initial state (ONLY ALLOWED IN CONSTRUCTOR)
        this.state = {
            greeting: 'Hello!'
        };
    }
    click(e) {
        this.setState({
              greeting: 'Hello World!'
        });
    }
    render() {
        return(
            <div>
                <p>{this.state.greeting}</p>
                <button onClick={this.click}>Click me</button>
            </div>
        );
    }
    
}

Utilizzo di setState() con una funzione come updater

//
// This is most often used when you want to check or make use 
// of previous state before updating any values.
//

this.setState(function(previousState, currentProps) {
  return {
    counter: previousState.counter + 1
  };
});

Questo può essere più sicuro dell'uso di un argomento oggetto in cui vengono utilizzate più chiamate a setState() , poiché più chiamate possono essere raggruppate insieme da React e eseguite contemporaneamente, ed è l'approccio preferito quando si usano gli oggetti di scena attuali per impostare lo stato.

this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });

Queste chiamate possono essere raggruppate insieme da React usando Object.assign() , facendo in modo che il contatore venga incrementato di 1 anziché di 3.

L'approccio funzionale può anche essere utilizzato per spostare la logica di impostazione dello stato al di fuori dei componenti. Ciò consente l'isolamento e il riutilizzo della logica di stato.

// Outside of component class, potentially in another file/module

function incrementCounter(previousState, currentProps) {
    return {
        counter: previousState.counter + 1
    };
}

// Within component

this.setState(incrementCounter);

Chiamando setState() con un oggetto e una funzione di callback

//
// 'Hi There' will be logged to the console after setState completes
//

this.setState({ name: 'John Doe' }, console.log('Hi there'));

Antipattern comune

Non dovresti salvare props nello state . È considerato un anti-modello . Per esempio:

export default class MyComponent extends React.Component {
    constructor() {
        super();

        this.state = {
            url: ''
        }

        this.onChange = this.onChange.bind(this);
    }

    onChange(e) {
        this.setState({
            url: this.props.url + '/days=?' + e.target.value
        });
    }

    componentWillMount() {
        this.setState({url: this.props.url});
    }

    render() {
        return (
            <div>
                <input defaultValue={2} onChange={this.onChange} />

                URL: {this.state.url}
            </div>
        )
    }
}

L' url prop viene salvato su state e quindi modificato. Invece, scegliere di salvare le modifiche in uno stato, quindi creare il percorso completo utilizzando sia lo state che gli props :

export default class MyComponent extends React.Component {
    constructor() {
        super();

        this.state = {
            days: ''
        }

        this.onChange = this.onChange.bind(this);
    }

    onChange(e) {
        this.setState({
            days: e.target.value
        });
    }

    render() {
        return (
            <div>
                <input defaultValue={2} onChange={this.onChange} />

                URL: {this.props.url + '/days?=' + this.state.days}
            </div>
        )
    }
}

Questo perché in un'applicazione React vogliamo avere un'unica fonte di verità, ovvero tutti i dati sono responsabilità di un singolo componente e di un solo componente. È responsabilità di questo componente archiviare i dati nel suo stato e distribuire i dati ad altri componenti tramite oggetti di scena.

Nel primo esempio, sia la classe MyComponent che la sua parent mantengono "url" all'interno del loro stato. Se aggiorniamo lo stato.url in MyComponent, queste modifiche non si riflettono nel genitore. Abbiamo perso la nostra unica fonte di verità, e diventa sempre più difficile monitorare il flusso di dati attraverso la nostra applicazione. Confrontalo con il secondo esempio: l'url viene mantenuto solo nello stato del componente principale e utilizzato come oggetto di supporto in MyComponent, pertanto manteniamo un'unica fonte di verità.

Stato, eventi e controlli gestiti

Ecco un esempio di un componente React con un campo di input "gestito". Ogni volta che cambia il valore del campo di input, viene chiamato un gestore di eventi che aggiorna lo stato del componente con il nuovo valore del campo di input. La chiamata a setState nel gestore eventi attiverà una chiamata per eseguire il render dell'aggiornamento del componente nella dom.

import React from 'react';
import {render} from 'react-dom';


class ManagedControlDemo extends React.Component {

  constructor(props){
    super(props);
    this.state = {message: ""};
  }

  handleChange(e){
    this.setState({message: e.target.value});
  }

  render() {
    return (
      <div>
        <legend>Type something here</legend>
          <input 
            onChange={this.handleChange.bind(this)} 
            value={this.state.message} 
            autoFocus />
        <h1>{this.state.message}</h1>
      </div>
   );
  } 
}


render(<ManagedControlDemo/>, document.querySelector('#app'));

È molto importante notare il comportamento di runtime. Ogni volta che un utente modifica il valore nel campo di input

  • handleChange sarà chiamato e così
  • setState sarà chiamato e così
  • render sarà chiamato

Quiz pop, dopo aver digitato un carattere nel campo di input, quali elementi DOM cambiano

  1. tutti questi - il livello più alto div, legend, input, h1
  2. solo l'input e h1
  3. Niente
  4. che cos'è un DOM?

Puoi sperimentare di più qui per trovare la risposta



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow