事情的通过是这样:你们最近可能常常会见到掘金上有个广告👇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 数据流实战
行了不扯淡了,喜欢我文章的朋友记得点关注!