Rumah >hujung hadapan web >tutorial js >Pemahaman mendalam tentang mekanisme kemas kini setState dalam React
Sebagai bahagian penting tindak balas, setState baris gilir berubah kepada keadaan komponen dan memberitahu React bahawa ia perlu memaparkan semula komponen ini dan subkomponennya dengan keadaan dikemas kini. Artikel berikut akan membawa anda melalui mekanisme setState dalam React. Saya harap ia akan membantu anda!
state
ialah konsep penting dalam React
. Kami tahu bahawa React
menguruskan komponen melalui pengurusan negeri. Jadi, bagaimanakah React
mengawal status komponen, dan bagaimanakah ia menggunakan status untuk mengurus komponen? [Cadangan berkaitan: Tutorial video Redis]
Kita semua tahu bahawa React
mengakses this.state
melalui state
dan mengemas kini this.setState()
melalui kaedah state
. Apabila this.setState()
dipanggil, React
akan memanggil semula kaedah render
untuk memaparkan semula UI
.
setState
sudah menjadi sangat biasa API
kami, tetapi adakah anda benar-benar memahaminya? Di bawah ini kami akan menyahsulit mekanisme kemas kini setState
bersama-sama.
Apabila semua orang mula-mula mula menulis React
, mereka biasanya menulis kod seperti this.state.value = 1
, yang salah sama sekali.
Nota: Jangan sekali-kali mengubah suai ini. nyatakan ini bukan sahaja pendekatan yang tidak cekap, tetapi ia juga mungkin digantikan dengan operasi seterusnya.
setState
menyedari state
kemas kini melalui mekanisme baris gilir. Apabila setState
dilaksanakan, state
yang perlu dikemas kini akan digabungkan dan dimasukkan ke dalam baris gilir status dan bukannya mengemas kini this.state
dengan segera Mekanisme baris gilir boleh mengemas kini state
secara efisien dalam kelompok. Jika nilai setState
diubah suai secara langsung tanpa melepasi this.state
, maka state
tidak akan dimasukkan ke dalam baris gilir status Apabila setState
dipanggil kali seterusnya dan baris gilir status digabungkan, pengubahsuaian langsung sebelumnya akan diabaikan. Diubah suai state
, menyebabkan ralat yang tidak dapat diramalkan.
Oleh itu, kaedah setState
harus digunakan untuk mengemas kini state
Pada masa yang sama, React
juga menggunakan mekanisme baris gilir status untuk melaksanakan kemas kini tak segerak setState
untuk mengelakkan kemas kini berulang yang kerap. state
. Kod yang berkaitan adalah seperti berikut:
// 将新的state合并到状态更新队列中 var nextState = this._processPendingState(nextProps, nextContext); // 根据更新队列和 shouldComponentUpdate 的状态来判断是否需要更新组件 var shouldUpdate = this._pendingForceUpdte || !inst.shouldCompoonentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext0;
Apabila setState
dipanggil, kaedah enqueueSetState
sebenarnya akan dilaksanakan dan baris gilir akan dikemas kini untuk partialState
dan _pendingStateQueue
Lakukan operasi cantum, dan operasi akhir enqueueSetState
melaksanakan state
kemas kini.
dan kaedah performUpdateIfNecessary
akan mendapat _pendingElement、_pendingStateQueue、_pendingForceUpdate
dan memanggil kaedah receiveComponent
dan updateComponent
untuk kemas kini komponen.
Jika shouldComponetUpdate
dipanggil dalam kaedah componentWillUpdate
atau setState
, maka this._pendingStateQueue != null
, maka kaedah performUpateIfNecessary
akan memanggil kaedah updateComponent
untuk mengemas kini komponen, tetapi updateComponent
kaedah akan Kaedah shouldComponentUpdate
dan componentWillUpdate
akan dipanggil, sekali gus menyebabkan gelung panggilan, menyebabkan penyemak imbas ranap apabila memori penuh.
Memandangkan setState
akhirnya melaksanakan enqueueUpate
kemas kini melalui state
, maka bagaimanakah enqueueUpdate
kemas kini state
Apa tentang?
Pertama sekali, lihat soalan berikut. Bolehkah anda menjawabnya dengan betul?
import React, { Component } from 'react' class Example extends Component { constructor() { super() this.state = { val: 0 } } componentDidMount() { this.setState({val: this.state.val + 1}) console.log(this.state.val) this.setState({val: this.state.val + 1}) console.log(this.state.val) setTimeout(() => { this.setState({val: this.state.val + 1}) console.log(this.state.val) this.setState({val: this.state.val + 1}) console.log(this.state.val) },0) } render() { return null } }
Dalam kod di atas, console.log
yang dicetak empat kali oleh val
ialah: 0、0、2、3
.
Jika hasilnya tidak betul-betul sama dengan jawapan dalam fikiran anda, maka adakah anda ingin tahu apa sebenarnya yang enqueueUpdate
lakukan?
Gambar di bawah ialah timbunan panggilan setState
yang dipermudahkan, perhatikan pertimbangan status teras.
setState
Timbunan panggilan dipermudah
Bagaimanakah ia membawa kepada pelbagai gelagat setState
yang berbeza?
我们先要了解事务跟 setState
的不同表现有什么关系。首先,我们把4次 setState
简单归类,前两次属于一类,因为他们在同一次调用栈中执行,setTimeout
中的两次 setState
属于另一类,因为他们也是在同一次调用栈中执行。我们分析一下这两类 setState
的调用栈。
在 componentDidMount
中直接调用的两次 setState
,其调用栈更加复杂;而setTimeout
中调用的两次 setState
,其调用栈则简单很多。下面我们重点看看第一类 setState
的调用栈,我们发现了 batchedUpdates
方法,原来早在 setState
调用前,已经处于batchedUpdates
执行的事务中了。
那batchedUpdates
方法,又是谁调用的呢?我们再往前追溯一层,原来是 ReactMount.js 中的 _renderNewRootComponent
方法。也就是说,整个将React组件渲染到DOM中的过程就处于一个大的事务中。
接下来的解释就顺理成章了,因为在componentDidMount
中调用setState
时,batchingStrategy
的 isBatchingUpdates
已经被设为true
,所以两次setState
的结果并没有立即生效,而是被放到了dirtyComponents
中。这也解释了两次打印 this.state.val
都是 0
的原因,因为新的 state
还没有被应用到组件中。
componentDidMount
中setState
的调用栈
setTimeout
中setState
的调用栈
再反观 setTimeout
中的两次setState
,因为没有前置的 batchedUpdate
调用,所以 batchingStrategy
的 isBatchingUpates
标志位是false
,也就导致了新的 state
马上生效,没有走到 dirtyComponents
分支。也就是说,setTimeout
中第一次执行 setState
时,this.state.val
为 1
, 而 setState
完成打印后打印时 this.state.val
变成了2
。第二次的 setState
同理。
前面介绍事务时,也提到了其在 React
源码中的多处应用,像 initialize、perform、close、closeAll、motifyAll
等方法出现在调用栈中,都说明当前处于一个事务中。
既然事务这么有用,我们写应用代码时能使用它吗?很可惜,答案是不能。尽管React
不建议我们直接使用事务,但在 React 15.0
之前的版本中还是为开发者提供了 batchedUpdates
方法,它可以解决针对一开始例子中setTimeout
里的两次 setState
导致两次 render
的情况:
import ReactDOM, { unstable_batchedUpates } from 'teact-dom' unstable_batchedUpates(() => { this.setState(val: this.state.val + 1) this.setState(val: this.state.val + 1) })
在 React 15.0
以及之后版本中,已经彻底将 batchUpdates
这个 API
移除了,因此不再建议开发者使用它。
在使用React
的setState
的过程中,了解setState
的实现原理,对setState
异步更新、setState
循环调用风险、setState
调用栈等进行更加全面的了解,才能让我们在遇到相关问题的时候更加游刃有余。
更多编程相关知识,请访问:编程入门!!
Atas ialah kandungan terperinci Pemahaman mendalam tentang mekanisme kemas kini setState dalam React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!