React 開發(fā)者常見的 3 個錯誤

關(guān)于前端開發(fā),我最開心的事情就是總有新的東西可以學(xué)習(xí)。但我們可能一輩子都在掌握各種編程語言、庫和框架,但仍然一無所知。
因為我們都在學(xué)習(xí),這也意味著我們都容易犯錯誤。沒關(guān)系,我們的目的是變得更好。如果你犯了一個錯誤并從中吸取教訓(xùn),你就做得很好!但是如果你沒有學(xué)到任何新的東西,并且不斷重復(fù)犯同樣的錯誤,emmm。。。可能你的職業(yè)生涯就會停滯不前。
本著這種精神,下面是我在 CodeReview 初級開發(fā)同學(xué)時經(jīng)常看到的三個錯誤。我們一起來 check 一下,然后討論如何改正它。
直接修改狀態(tài)
在更新 React 組件狀態(tài)時,最重要的是調(diào)用 setState 方法去更新,并且傳入的對象是一個新的副本,而不是直接修改之前的狀態(tài)。如果你錯誤地修改了組件的狀態(tài),React Diff 算法將無法捕獲更改,而且你的組件也無法正確地更新。讓我們來看一個例子。
假設(shè)你有這樣的狀態(tài):
this.state?=?{
????colors:?['red',?'green',?'blue']
}
現(xiàn)在你想要給這個數(shù)組添加顏色:
//?方法1:
this.state.colors.push('yellow’)
//?方法2:
this.state.colors?=?[...this.state.colors,?'yellow’]
這兩種方法都是錯誤的!在更新類組件中的狀態(tài)時,必須使用 setState 方法,并且應(yīng)該注意不要改變原始對象。下面是添加元素到數(shù)組的正確方法:
this.setState(prevState?=>?({?colors:?[...prevState.colors,?'yellow']?}))
忘記了 setState 的批量更新
setState 有兩種使用方法。第一種方法是傳入一個對象作參數(shù)。第二種方法是傳入一個函數(shù)作參數(shù)。你知道這兩種方法分別應(yīng)該在什么時候使用嗎?
例如,如果你有一個可以啟用或禁用的按鈕,那么你可能會有一個名為 isDisabled 的狀態(tài),其中包含一個布爾值。如果你想切換這個按鈕的狀態(tài),你可能很會寫這樣的一段代碼:
//?setState?使用一個對象作參數(shù)
this.setState({?isDisabled:?!this.state.isDisabled?})
那么,這有什么問題呢?問題在于 React 狀態(tài)更新可以批處理(batchUpdate),這意味著多個狀態(tài)更新可以在一個更新周期中發(fā)生。如果你的更新將被批處理,并且你對 isDisabled 狀態(tài)有多個更新,那么最終結(jié)果可能不是你所期望的。
更新狀態(tài)的更正確的方法是提供前一個狀態(tài)的函數(shù)作為參數(shù):
this.setState(prevState?=>?({?isDisabled:?!prevState.isDisabled?}))
現(xiàn)在,即使你的狀態(tài)更新被批處理,并且有多個更新都在操作 isDisabled 狀態(tài),但每個更新都依賴于正確的先前狀態(tài),因此你總是會得到預(yù)期的結(jié)果。
類似的遞增計數(shù)器也是如此。
//?不要這樣做
this.setState({?counterValue:?this.state.counterValue?+?1?})
//?正確的寫法
this.setState(prevState?=>?({?counterValue:?prevState.counterValue?+?1?}))
忘記了 setState 是異步的
最后,記住 setState 是一種異步方法是很重要的。
初學(xué)者可以先理解成異步,但嚴(yán)格意義上說,需要區(qū)分條件來看。
如:在 React 內(nèi)部生命周期以及事件處理函數(shù)中是異步的。
如:在 setTimeout 函數(shù)中調(diào)用 setState 卻是同步的。
舉個例子,假設(shè)我們有一個如下狀態(tài)的 React 組件:
this.state?=?{?name:?'John'?}
有一個方法更新狀態(tài),并將新的狀態(tài)打印到控制臺上:
this.setState({?name:?'Matt'?})
console.log(this.state.name)
你可能認(rèn)為打印出來的會是?Matt?,但它不會! 它會打印?John?!
這是因為 setState 是異步的。這意味著執(zhí)行到 setState 時,會把真正更新的操作放在異步隊列中去執(zhí)行,但它下面的同步代碼將立即執(zhí)行,所以打印出來的 state 就不是最新的。
如果你想拿到更新完成后的最新狀態(tài),React 允許你傳一個回調(diào)函數(shù),該函數(shù)會在更新完成后運行。
this.setState({?name:?'Matt'?},?()?=>?console.log(this.state.name))
問題解決了! 現(xiàn)在它可以正確地記錄?Matt?了。
總結(jié)
好了!以上就是今天給大家分享的 React 中的三個常見錯誤及其糾正方法。記住,犯錯誤是正常的,但要避免犯同樣的錯誤。你在學(xué)習(xí)、我在學(xué)習(xí)、我們都在學(xué)習(xí)。讓我們繼續(xù)學(xué)習(xí),一起變得更好。
