setState vs replaceState in React.js


96

Sono nuovo nella libreria React.js e stavo esaminando alcuni tutorial e mi sono imbattuto in:

  • this.setState
  • this.replaceState

La descrizione fornita non è molto chiara (IMO).

setState is done to 'set' the state of a value, even if its already set 
in the 'getInitialState' function.

Allo stesso modo,

The replaceState() method is for when you want to clear out the values 
already in state, and add new ones.

Ho provato this.setState({data: someArray});seguito da this.replaceState({test: someArray});e poi li console.logged e ho scoperto che statela società aveva sia datae test.

Poi, ho provato this.setState({data: someArray});seguito da this.setState({test: someArray});e poi li console.logged e ho scoperto che stateancora una volta aveva sia datae test.

Allora, qual è esattamente la differenza tra i due?


1
Il tuo primo esempio è impreciso. replaceState rimuoverà lo stato precedente. Probabilmente lo stai testando in modo errato.
Brigand

1
Non stavo cercando modifiche in una richiamata. Forse è per questo ...
myusuf

Risposte:


138

Con setStatelo stato attuale e precedente vengono fusi. Con replaceState, elimina lo stato corrente e lo sostituisce solo con ciò che fornisci. Di solito setStateviene utilizzato a meno che non sia necessario rimuovere le chiavi per qualche motivo; ma impostarli su false / null è solitamente una tattica più esplicita.

Sebbene sia possibile, potrebbe cambiare; replaceState attualmente utilizza l'oggetto passato come stato, cioè replaceState(x), e una volta impostato this.state === x. Questo è un po 'più leggero di setState, quindi potrebbe essere utilizzato come ottimizzazione se migliaia di componenti impostano frequentemente i propri stati.
L'ho affermato con questo caso di prova .


Se il tuo stato attuale è {a: 1}, e chiami this.setState({b: 2}); quando lo stato sarà applicato, lo sarà {a: 1, b: 2}. Se chiamassi il this.replaceState({b: 2})tuo stato sarebbe {b: 2}.

Nota a margine: lo stato non viene impostato immediatamente, quindi non farlo this.setState({b: 1}); console.log(this.state)durante il test.


1
Ancora poco chiaro per me. Puoi fare un esempio in cui usarne uno sull'altro cambia il risultato, cioè questa fusione a cui ti riferisci ...
Serj Sagan

1
Come c'è uno stato precedente e uno stato attuale, come in, come possiamo accedervi? Inoltre, ho passato un oggetto per sostituire lo stato, ma i dati di stato precedenti erano ancora presenti.
myusuf

1
Allora quando viene impostato lo stato? Come in quando posso console.log e testarlo?
myusuf

21
@myusuf.setState({...}, callback)
Brigand

46

Definizione per esempio:

// let's say that this.state is {foo: 42}

this.setState({bar: 117})

// this.state is now {foo: 42, bar: 117}

this.setState({foo: 43})

// this.state is now {foo: 43, bar: 117}

this.replaceState({baz: "hello"})

// this.state. is now {baz: "hello"}

Prendi nota di questo dalla documentazione , però:

setState () non modifica immediatamente this.state ma crea una transizione di stato in sospeso. L'accesso a this.state dopo aver chiamato questo metodo può potenzialmente restituire il valore esistente.

Lo stesso vale per replaceState()


14

Secondo i documenti , replaceStatepotrebbe essere deprecato:

Questo metodo non è disponibile sui componenti della classe ES6 che estendono React.Component. Potrebbe essere rimosso completamente in una versione futura di React.


Esiste un metodo di sostituzione simile?
zero_cool

1
Per un metodo "simile", potresti usare this.setState ({all: undefined, old: undefined, keys: undefined, new: value})
Wren

@Wren, cos'è questo? Questa firma ufficiale serve a ripristinare lo stato?
Verde

No, sta solo impostando esplicitamente lo stato preesistente su undefined che è il risultato netto di "replaceState" senza tutte le chiavi esistenti.
Wren

2

Poiché replaceStateora è deprecato, ecco una soluzione molto semplice. Anche se probabilmente è abbastanza raro che tu debba / dovresti ricorrere a questo bisogno.

Per rimuovere lo stato:

for (const old_key of Object.keys(this.state))
    this.setState({ [old_key]: undefined });

Oppure, in alternativa, se non vuoi avere più chiamate a setState

const new_state = {};
for (const old_key of Object.keys(this.state))
    new_state[old_key] = undefined;
this.setState(new_state);

In sostanza, tutte le chiavi precedenti nello stato ora vengono restituite undefined, il che può essere facilmente filtrato con ifun'istruzione:

if (this.state.some_old_key) {
    // work with key
} else {
    // key is undefined (has been removed)
}

if ( ! this.state.some_old_key) {
    // key is undefined (has been removed)
} else {
    // work with key
}

In JSX:

render() {
    return <div>
        { this.state.some_old_key ? "The state remains" : "The state is gone" }
    </div>
}

Infine, per "sostituire" lo stato, combina semplicemente il nuovo oggetto di stato con una copia del vecchio stato che è stato undefinede impostalo come stato:

const new_state = {new_key1: "value1", new_key2: "value2"};
const state = this.state;

for (const old_key of Object.keys(state))
    state[old_key] = undefined;

for (const new_key of Object.keys(new_state))
    state[new_key] = new_state[new_key];

this.setState(state);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.