還在用useState來定義數據嗎?教你個更好的方案:useImmer!

以前編寫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寫法要求每次都返回一個新的引用,在類組件走遍天下的那個時代,state這個變量幾乎存儲了此組件中的所有數據,便於集中訪問與管理。

Hooks時代

用了函數式組件定義數據就不能再這麼定義了,假如你要是還像以前一樣那麼寫:

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

use-immer

來看看useImmer是怎麼撰寫上述邏輯的:

// 定義
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. 而另一個不用以外還有一個需要注意的地方:

原生的setState直接可以當作返回值,而這個useImmer生成的盜版useState修改後的值不能被直接當作返回值返回,所以需要在函數體外面有大括號。
當然也可以自定義返回值,返回什麼值就會更新成什麼值。

喜歡我文章的朋友記得關注+點贊啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章