來自《React Hooks 與 Immutable》小冊做者'神三元'的靈魂拷問

事情通過

事情的通過是這樣:你們最近可能常常會見到掘金上有個廣告👇git

而後我看了評價感受好像挺不錯的,就買了(反正也不貴),加羣了之後感受做者很用心,不過最近項目一直在用Vue作PC端,就沒怎麼看這個小冊,尋思忙完這段時間,過年的時候看。
可是就在這時我忽然注意到了三元老師在推薦 immer之後就有好多人在問 immer是啥?
心血來潮的我決定是時候要給你們好好科普一下了,這麼好用的東西應該儘快讓你們都上手啊,否則做者心灰意冷了不繼續維護了怎麼辦?因而我寫了一篇文章: 2020要用immer來代替immutable優化你的React項目
而後我發到了羣裏,並@了三元老師:

正當我暗自得意的時候他忽然給我來了個靈魂拷問:
雖然最後他說了 immer更好用,可是我卻開心不起來了,由於他問了我一個問題我沒有回答上來:useImmer有什麼優點?(由於個人那篇文章裏寫了用useImmer代替useState)👇
寫文章的時候是參考的 useImmer官方文檔,這個文檔是這麼寫的:
翻譯: useImmer(initialState)和useState很是類似,這個方法返回一個數組,數組中第一個值是當前的state,第二個值是一個更新函數,更新函數接受一個函數來做爲參數,這個函數的參數能夠很是自由的去更改,當函數執行完以後將會生成一個不可變數據做爲新的state

當時我並無仔細的看這句話,注意力都集中在他文檔的那個小案例上了,沒有深刻的去思考,結果被三元老師一語中的點醒了我:useImmer和useState相比它的優點到底在哪?github

前兩天一直在加班忙項目,甚至連2020年的第一天都在加班-.-! 也沒時間去想這些,今天忙完了忽然想起這件事,因而又去仔細看了一眼,終於明白了它比useState好在哪!redux

更加便捷的存儲及修改state數據

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 數據流實戰

行了不扯淡了,喜歡我文章的朋友記得點關注!

後續

三元老師在這裏道出了useImmer的使用場景,若是你們的業務場景與三元老師所說的用hooks代替redux場景相似,就能夠在項目中試試這個神奇的hook!
相關文章
相關標籤/搜索