前序
书接上文,我写了一篇 redux和react-dedux 的文章,讲了何为redux、redux的基本实现原理,以及react-redux是如何去使用的(没有看过的同学建议前往上一篇看看),但是在涉及使用react-redux这块内容上只涉及了类组件如何去获取redux中的数据并如何通过dispatch去进行更新state,但是在函数组件上如何通过Hook去更方便的使用redux并没有提及,本篇主要内容就是对上一篇的补充,讲讲react-redux中的Hook;
先复习一下react不使用Hook是如何使用redux:
首先不管是类组件还是函数组件,都需要定义好reducer方法,去创建一个store,在根组件中通过Provider组件给每一个组件通过context的方式传入store,在通过connect高阶函数
,传入ui组件,并通过mapStateToProps、mapDispatchToProps方法去为UI组件添加对应获取store的state、dispatch作为参数供UI组件用,以此来生成容器组件;
但是在函数组件中,redux提供了一些Hook,让我们能更方便的使用redux;
react-redux中的Hook
在redux7.1开始,redux就提供了Hook的方式,在函数组件中在也不需要编写connect以及对应的映射函数了
useSelector
useSelector的作用就是将state映射到组件中,你可以简单的理解为代替了mapStateToProps
import { useSelector } from 'react-redux';
const Demo = () => {
const { text } = useSelector((state) => {
return {
text: state.text,
}
})
return (
<div>
{text}
</div>
)
}
如上面的上面的例子,我们可以往useSelector中入一个回调函数作为参数,这个回调函数会将store的state作为它的参数; 回调函数的返回值要求是一个对象, 在对象编写要使用的数据, 我们可以直接对这个返回的对象进行解构, 拿到我们要使用state中的数据;
我们还可以往useSelector中传入另外一个函数作为第二个参数,去判断是否组件重新渲染(如果不传,useSelector会默认比较我们前后返回的两个对象是否完全相等“===”,我们的state一般不会是一个基本数据类型,不然还用个锤子redux,一般都是对象,那么必然就导致每次结果都是false,然后重新渲染);
那我们想要在数据值没有变动的时候组件不重新渲染组件就要利用好第二个传参:
可以使用react-redux提供的shallowEqual函数、lodash的isEqual(), 或者自己定义的函数,去判断前后两次是否真的不一样,从而减少渲染的次数;
import { useSelector, shallowEqual } from 'react-redux';
const Demo = () => {
const { text } = useSelector((state) => {
return {
text: state.text,
}
}, shallowEqual)
return (
<div>
{text}
</div>
)
}
如上面的例子,加上后组件只有在test真的发生值的变更时才会进行重新渲染;
useDispatch
这个Hook使用很简单,你可以简单理解为代替mapDispatchToProps
import { useDispatch } from 'react-redux';
const Demo = () => {
const dispatch = useDispatch();
const onClickBtn = () => {
dispatch({
type: 'CHANGE_TEXT',
text: 'new text',
})
}
return (
<buttom onClick={onClickBtn}>change text</buttom>
)
}
如上面的例子,通过useDispatch方法返回的dispatch,我们就可以使用dispatch向store发送action,更新state;
useStore
通过useStore我们可以获取store
import { useStore } from 'react-redux';
const Demo = () => {
const store = useStore();
return (
<div>{store.getState().text}</div>
)
}
总结
有了useStore、useSelector、useDispatch这三个Hook(react-redux提供的Hook,非官方提供),是不是我们在函数组件中使用redux就变得更方便啦,我们可以不使用connect结合mapStateToProps、mapDispatchToPropsd也能去获取store、store中state,以及对store中state进行更新啦
ps:不管是用Hook还是connect高阶函数,通过Provider组件将store传给所有组件这些还是挺繁琐的,大家可以再去看看mobx怎么样😜