setState vs replaceState di React.js

96

Saya baru mengenal Perpustakaan React.js dan saya telah mempelajari beberapa tutorial dan saya menemukan:

  • this.setState
  • this.replaceState

Deskripsi yang diberikan tidak terlalu jelas (IMO).

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

Demikian pula,

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

Saya mencoba this.setState({data: someArray});diikuti this.replaceState({test: someArray});dan kemudian menghibur mereka dan saya menemukan bahwa statesekarang memiliki keduanyadata dan test.

Kemudian, saya mencoba this.setState({data: someArray});diikuti this.setState({test: someArray});dan kemudian konsol.logged mereka dan saya menemukan bahwa statelagi memiliki keduanyadata dan test.

Lalu, apa sebenarnya perbedaan keduanya?

myusuf
sumber
1
Contoh pertama Anda tidak akurat. replaceState akan menghapus status sebelumnya. Anda mungkin mengujinya dengan tidak benar.
Brigand
1
Saya tidak mencari perubahan dalam panggilan balik. Mungkin itu sebabnya ..
myusuf

Jawaban:

138

Dengan setStatestatus saat ini dan sebelumnya digabungkan. Dengan replaceState, itu membuang keadaan saat ini, dan menggantinya dengan hanya apa yang Anda berikan. BiasanyasetState digunakan kecuali Anda benar-benar perlu menghapus kunci karena suatu alasan; tetapi menyetelnya ke false / null biasanya merupakan taktik yang lebih eksplisit.

Meskipun mungkin, itu bisa berubah; replaceState saat ini menggunakan objek yang diteruskan sebagai status, yaitu replaceState(x), dan setelah disetel this.state === x. Ini sedikit lebih ringan dari setState, jadi ini dapat digunakan sebagai pengoptimalan jika ribuan komponen sering menyetel statusnya.
Saya menegaskan ini dengan kasus uji ini .


Jika keadaan Anda saat ini {a: 1}, dan Anda menelepon this.setState({b: 2}); ketika negara diterapkan, itu akan terjadi {a: 1, b: 2}. Jika Anda menelepon this.replaceState({b: 2})negara Anda akan {b: 2}.

Catatan samping: Status tidak diatur secara instan, jadi jangan lakukan this.setState({b: 1}); console.log(this.state)saat menguji.

Perampok
sumber
1
Masih belum jelas bagiku. Dapatkah Anda memberikan contoh di mana menggunakan salah satu dari yang lain mengubah hasilnya, yaitu penggabungan yang Anda maksudkan ...
Serj Sagan
1
Bagaimana ada keadaan sebelumnya dan keadaan saat ini, seperti, bagaimana kita bisa mengaksesnya? Juga, saya melewatkan objek untuk menggantikan status, tetapi data status sebelumnya masih ada.
myusuf
1
Jadi, kapan negara ditetapkan? Seperti kapan saya bisa console.log dan mengujinya?
myusuf
21
@myusuf.setState({...}, callback)
Brigand
46

Definisi dengan contoh:

// 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"}

Catat ini dari dokumen , meskipun:

setState () tidak langsung memutasi this.state tetapi membuat transisi status tertunda. Mengakses this.state setelah memanggil metode ini berpotensi mengembalikan nilai yang sudah ada.

Hal yang sama berlaku untuk replaceState()

Grav
sumber
14

Menurut dokumen , replaceStatemungkin tidak digunakan lagi:

Metode ini tidak tersedia pada komponen kelas ES6 yang memperluas React.Component. Ini dapat dihapus seluruhnya dalam versi React yang akan datang.

Liran Brimer
sumber
Apakah ada metode penggantian yang serupa?
zero_cool
1
Untuk metode "serupa", Anda dapat menggunakan this.setState ({all: undefined, old: undefined, keys: undefined, new: value})
Wren
@Wren, apa ini? Apakah tanda tangan resmi ini untuk menyetel ulang status?
Hijau
Tidak, ini hanya secara eksplisit menyetel status yang sudah ada ke tidak ditentukan yang merupakan hasil bersih dari "replaceState" tanpa semua kunci yang ada.
Gelatik
2

Sejak replaceState sekarang sudah usang, berikut ini solusi yang sangat sederhana. Meskipun mungkin sangat jarang bahwa Anda akan / harus menggunakan kebutuhan ini.

Untuk menghapus negara:

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

Atau, sebagai alternatif, jika Anda tidak ingin memiliki banyak panggilan setState

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

Pada dasarnya, semua kunci sebelumnya dalam status sekarang kembali undefined, yang dapat dengan mudah difilter dengan ifpernyataan:

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
}

Di JSX:

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

Terakhir, untuk "menggantikan" status, cukup gabungkan objek status baru dengan salinan status lama yang telah ada undefined, dan setel sebagai status:

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);
stormpie
sumber