深入理解redux
今天在做项目的时候,对redux有了一些新的感悟,同时,又参考了一些知乎大神的redux专栏(建议大家有空也去看下),特地写篇博客和大家分享下,好了,话不多说,进入正题。
首先,我们来了解下redux为什么会产生(就是这货到底是出来干嘛的),原因是当我们的应用越来越复杂的时候,就会出现父组件套子组件,子组件又套子组件,一层一层的嵌套下去,此时当顶层父组件和底层子组件通信时,就只能通过props一层一层的传递下去,是不是很恶心?redux就是来解决这个问题的。
那么问题就来了,redux到底是怎么解决的呢?redux其实是在里层的组件和顶层组件中开了一个“虫洞”,使里层组件可以直接和顶层组件进行通信,然后呢?怎么通信的呢?整个过程是这样的:
store(state) --->view ---> action ---> reducer ---> store(state) ---> view
首先store(state)决定了view,也就是呈现在用户面前的界面,然后用户与view的交互,会产生action,比如用户说我点击你啦,此时就调用了action的点击动作,然后reducer就会调用这个点击动作该执行什么效果,执行完毕之后返回给store,告诉它你的state该改变了,然后store改变它的state,以致view也随之改变。
感觉有点懵?不要着急,我们先回想下react中父组件是怎么和子组件通信的,父组件通过自己的state转化为子组件的props,来控制子组件;子组件通过父组件传递过来的带参函数,通过传递的参数来反馈父组件。这个简单吧?那再想一下,我们实际写代码的时候是怎么获取redux中的数据的?this.props.userinfo,我们是怎么触发action的呢?this.props.userinfo.update()。发现什么了吗?有没有感觉有些熟悉了?里层组件获取数据,是通过props,里层组件触发action,是通过带参的函数,这不就是简单的父组件和子组件之间的通信方式吗?这到底是怎么办到的?还记得上文提到的“虫洞”吗?就是这个东西提供了这种通信,使里层组件可以直接和顶层组件通信。
什么鬼?那子组件本身的父组件弄过来的props呢?不对啊,好像本身父组件传来的props还是可以使用啊,这是怎么搞的?我们再回想下this.setState()是怎么办到的,没错,这里也是使用了调和,实际上,我们连接上redux的组件,它的props并不是通过其父组件传递过来的,而是通过其父组件和redux调和之后,connect重新生成的调和组件传递过来的,这时候我们应该明白了,所谓的虫洞,就是开辟的一个组件和经过调和的父组件之间的通道。
鉴于上述分析,那我们不妨思考下,目前我们有两种组件间的通信方式了,通过props传递和通过redux传递,我们全部使用props和全部使用redux,理论上是都可以成功完成通信的,那到底什么时候我们该使用props,什么时候使用redux呢?有了redux,我们要放弃props的传递方式吗?,请注意,以下内容纯粹是个人看法了,有不对的地方欢迎大家批评指出。
我认为redux主要有两个使用场景,其一:必然是redux本身要解决的深层嵌套问题,目前阶段我的处理方式是,传递两层可以完成通信的,使用props传递,大于两层通信的,使用redux去解决;其二:我们的顶层组件是app组件,下一层基本就是views的各个页面的组件了,假如我们有两个页面page1和page2,这两个页面要通信怎么办呢?page1通过函数改变app的state,再通过app的state改变page2,页面如果多一些,是不是会造成app里面的state略多了?而且,redux里面本身就是和顶层组件的一种调和,而我们的page1和page2的父组件,基本就是我们的顶层组件,因此,为了避免app组件的state过多,对于跨页面之间的通信,我也采用了redux的通信方式。