React已经火到不行了,相信大家伙儿或多或少的看过或者自己动手实践过一些demo,所以关于一些基础的概念我这里就不再赘述,大家可以在km或者google上搜索“React入门”。网上的大多数demo都是静态渲染的例子,只是玩具,并不能很好的体现实际开发过程。兴趣部落PC版在生产环境采用了React,这里给大家分享一下PC部落实战过程中,个人觉得比较重要的一些点。
本文分三个部分。
- React生命周期
- 跨组件通信
- 实际场景应用
React生命周期
React只是一个view层的框架,它什么功能都不提供(相对于Angular的完整性),实际开发中的需求万紫千红,需要灵活多变,React自身提供了一套完美的生命周期接口,让我们可以随心所欲。关于React生命周期的理解,我们可以把它理解为游戏里打造装备的过程。先脑补一下装备打造的过程
收集原材料 -> 加工原材料 -> 铁匠铺打造 -> 完成初级装备 -> 打boss获得高级材料 -> 对比新材料与旧材料的差别 -> 发现更好,加工新材料 -> 铁匠铺打造 -> 升级为高级装备 -> 等级过高,装备不适用,分解或给NPC
嗯,基本是这个样子。
其实,React的生命周期与它有异曲同工之处(设计模式无处不在啊)。ok,我们来看下React的生命周期。 官方文档写的很清楚,React生命周期分为3个过程。
Mouting
收集材料,打造一件初级装备
- getInitialState (收集原材料) 初始化state数据,只会调用一次
- componentWillMount (加工原材料) 组件挂载前调用,谐音 “喂马”
- render (铁匠铺打造) 组装虚拟DOM,然后渲染到页面上
- componentDidMount (完成初级装备) 挂载完成,可以访问dom元素了。
Update(更新)
打boss,用获得的高级材料来升级装备
- componentWillReceiveProps (获得高级原材料) 接受到新的props时调用
- shouldComponentUpdate (对比原材料是否更好) 是否需要更新DOM
- componentWillUpdate (加工原材料) 更新之前调用
- render (铁匠铺打造) 组装虚拟DOM,然后渲染到页面上
- componentDidUpdate (完成高级装备) 更新完成
UnMounting(卸载)
淘汰装备,释放内存
- componentWillUnmount React做组件卸载时会自动移除掉组件上的事件绑定,但是我们自己通过原生方法绑定的事件就需要通过componentWillUnmount来自行解绑了
可以很清晰的看到,在componentDidMount和componentDidUpdate方法中我们可以去获取到dom对象,这个时间点可以用第三方框架了,比如初始化视频、音乐播放器等用react比较难造的轮子。
理解透了生命周期,基本上我们就可以快乐的去开发了。
跨组件通信
生命周期都是一个组件自己玩,实际开发中我们是需要跟小伙伴一起玩儿的,那组件之间怎么交流呢?
交流的对象: 父子组件交流、无关联组件交流
1. 父组件调用子组件
通过React提供的ref属性,直接调用子组件的实例
2. 子组件调用父组件
父组件给子组件传递的props里可以是函数,子组件可直接调用
3. 无直接关系的组件调用
这个就相对复杂一些了。react组件对外都是一个黑盒,常规方法调用,可能需要渗透很多耦合代码。有经验的程序猿应该很快能想到用pub/sub的设计模式来解决这个问题。对,我们就是要采用这样模式,但是我们在多人模式下写pubsub时,很多时候pubsub散落在各地,维护很苦逼。 React提供了一个基于pub/sub的Flux架构,可以让我们很清晰的了解整个订阅发布的过程,维护起来也相对轻松。
Flux倡导的是单向数据流的原则,在这种架构下,通过Store存放应用程序的状态数据。当应用状态发生变化时,Store 可以发出事件,通知应用的组件并进行组件的重新渲染。另外,Dispatcher起到中央hub的作用,它为组件(View)和Store构建 起了桥梁。此外,你可以在组件上调用action,它会向Store发起事件。Store正是通过订阅这些事件,并根据事件的触发来改变 应用程序的内部状态的
兴趣部落采用的Reflux,Reflux是基于flux架构实现的单向数据流类库,使用非常的便捷。
网上关于flux与reflux原理的讲解非常多,我这里就不再赘述,有兴趣的同学可以自行搜索。
案例分析
吃透了生命周期,了解了跨组件数据通信,再学点jsx的语法,基本我们就可以无限造轮子了(用了React后,你需要造非常非常多的轮子)。我们来看看兴趣部落里的一些场景的实现
1. 滚动加载
流程是这样子的:
那这个过程对应到生命周期是什么样子的呢?
(有些地方没有标注上对应的周期方法,图会画的太复杂…)
来看看代码吧。(部分代码是伪代码)
这个例子算是比较常见的,大家可以再根据它体会一下生命周期,常用的方法都这个示例里都有涉及。
2. 跨组件通信场景: 回复评论后,在评论列表底部显示刚刚发表的评论。
这里有两个组件:列表组件和评论组件 在评论发表成功后如何通知到列表组件来更新呢,没什么好说的,直接看代码吧。
其他
可能会有人问我为什么不用redux而用reflux
- 我们开始预研的时候redux还没出世,而reflux是当时最火的flux框架
- 从开始看reflux到使用reflux,我只用了1个小时而redux我看了一整天文档都晕乎乎的(我太愚钝(┬_┬))
对于reflux的使用,也有两种流派:
- 所有的异步数据加载(ajax拉取cgi数据)都在store里进行,然后派发给组件
- 数据加载放在组件内进行,reflux只用于跨组件通信。 第一种让整个架构看起来更像MVC,流程也比较清晰。而我个人更偏向于第二种,这样可以保证一个组件的完整性,组件的插拔会变的很轻松,对于组件的复用及维护也更便利。但也不能完全这样,对于多个组件共享一份数据源的情况,还是在store加载并派发比较合适,根据实际业务情况来定夺。
以上是我在兴趣部落React实践的一些体会,感谢阅读!如果有什么不对的地方,还请斧正!谢谢!
扫码下方二维码,
随时关注更多前端干货文章!
▼
微信:IMWebTech