事情的通過是這樣:你們最近可能常常會見到掘金上有個廣告👇git
當時我並無仔細的看這句話,注意力都集中在他文檔的那個小案例上了,沒有深刻的去思考,結果被三元老師一語中的點醒了我:useImmer和useState相比它的優點到底在哪?github
前兩天一直在加班忙項目,甚至連2020年的第一天都在加班-.-! 也沒時間去想這些,今天忙完了忽然想起這件事,因而又去仔細看了一眼,終於明白了它比useState好在哪!redux
Hooks上市以前咱們是這麼定義state的:數組
state = {
people: [
{
name: '馬雲',
englishName: 'Jack Ma'
},
{
name: '馬化騰',
englishName: 'Pony Ma'
},
{
name: '李彥宏',
englishName: 'Robin Li'
}
]
}
複製代碼
這種狀況下若是用 setState({…}) 這種形式的話修改數據的話會比較麻煩,因此推薦函數式寫法:函數
this.setState(state => {
state.people[2].englishName = 'Robin Lee'
return {...state}
});
複製代碼
函數式setState寫法要求每次都返回一個新的引用,不過自從有了hooks組件定義數據就不能再這麼定義了,假如你要是還像之前同樣那麼寫:post
const [state, setState] = useState({
people: [
{
name: '馬雲',
englishName: 'Jack Ma'
},
{
name: '馬化騰',
englishName: 'Pony Ma'
},
{
name: '李彥宏',
englishName: 'Robin Li'
}
]
});
複製代碼
那麼你的setState就不太好改了,相信用過React Hooks的小夥伴們都能懂,並且這也不是被推薦的寫法,通常來講咱們會盡量的細分:優化
const [jack, setJack] = useState({
name: '馬雲',
englishName: 'Jack Ma'
});
const [pony, setPony] = useState({
name: '馬化騰',
englishName: 'Pony Ma''
});
const [robin, setRobin] = useState({
name: '李彥宏',
englishName: 'Robin Li'
});
複製代碼
這樣的話修改數據就方便多了,粒度也更細膩,可是就是寫起來麻煩、不夠直觀、代碼量也更多,尤爲是當你的數據量比較大、或者嵌套層級比較深的狀況下那簡直就是一場災難。那麼怎麼樣才能既像之前setState那樣方便快捷,同時又能使用函數式組件呢?聰明的朋友們應該猜也猜到了:useImmer!
來看看useImmer是怎麼撰寫上述邏輯的:this
// 定義
const [state, setState] = useImmer({
people: [
{
name: '馬雲',
englishName: 'Jack Ma'
},
{
name: '馬化騰',
englishName: 'Pony Ma'
},
{
name: '李彥宏',
englishName: 'Robin Li'
}
]
})
// 修改
setState(state => {state.people[2].name = 'Robin Lee'})
複製代碼
不管嵌套層級多麼深,不管數據有多麼複雜,useImmer總能讓你找到當年 this.setState(state => state.people[2].name = 'Robin Lee') 的感受,可是不一樣之處除了一個要用 this. 而另外一個不用之外還有一個須要注意的地方:spa
原生的setState直接能夠看成返回值,而這個useImmer生成的盜版useState修改後的值不能被直接看成返回值返回,因此須要在函數體外面有大括號。
固然也能夠自定義返回值,返回什麼值就會更新成什麼值。翻譯
更具體的用法能夠參照:2020要用immer來代替immutable優化你的React項目
寫到這裏已經接近尾聲了,此次寫完了我要繼續發羣裏@三元老師,看看此次他還會不會以爲useImmer這個鉤子函數沒有卵用了(點贊多的話後續我會繼續更新文章發三元老師對話的截圖)順便免費給三元先生打個廣告:React Hooks 與 Immutable 數據流實戰
行了不扯淡了,喜歡我文章的朋友記得點關注!