面向界面编程可分为三部分:界面、数据、数据操作
组件的生命周期:
- 挂载,挂载过程中会依次执行下面的函数:
a. constructor()
b. componentWillMount()
c. render()
d. componentDidMount() - 更新(场景:父组件更新,自身状态变化,自身强制更新),组件更新会依次执行下面函数:
a. componentWillReceiveProps()父组件更新调用
b. shouldComponentUpdate()父组件更新和自身状态变化都会调用
c. componentWillUpdate()
d. render()
e. componentDidUpdate() - 卸载
a. componentWillUnmount()
组件的通信
- 父子组件:子=>父,父=>子,另外可以封装消息发布订阅模块,统一管理消息。
- 爷孙组件:此处可以泛指多代,最笨的办法以父子模式层层传递,另一种说使用context桥梁,但这样在维护上层组件的context属性时,要充分考虑子组件中的各种引用,也有可能造成重名问题。
- 兄弟组件:兄弟组件可以共有一个父组件达成交互,可以考虑使用观察者模式。
- 任意组件:共同祖先、消息中间件(观察者模式)、状态管理Redux
组件的设计与抽象
- 组件应该只通过属性输入,避免使用context,更要避免读取全局变量、系统I/O
- 组件的属性应有默认值,减少需要传递的参数
- 组件的属性应当只用简单值,避免使用复杂的数据结构对象,简单属性值更易于维护,复杂数据结构要配合说明
- 组件要足够健壮,充分考虑边界异常情况,做好属性的类型验证
注意:
- setState是异步执行,也就是说在setState后不一定能够马上读取到state的变化,如要在setState后执行一些操作,则需传入回调函数。
- 在render中不要使用setState,从生命周期来理解,会造成死循环。
- 在组件层面的解藕要考虑每次状态变化造成的重渲染,所影响的区域应尽可能小。
Redux
Redux的官方定义:Redux is a predictable state container for Javascript APP.翻译过来就是Redux是一个可预测状态的“容器”。关键部分在于“可预测”和“可追溯”。
背后的哲学
Single Source of truth:单一真相,单一溯源
State is read-only:状态只读
Changes are made with pure functions called reducer:使用reducer函数来接收action,并执行页面状态怒树的变化。
纯函数:对于指定输出,返回指定确定结果,并且不存在副作用(不会影响传入参数),确保不影响传入参数的关键就是copy。
Redux中所有由开发者定义的reducer函数都需要是纯函数。
高阶组件设计原则:
- 高阶组件不可以直接修改接收到的组件的自身行为,只能进行功能组合。
- 高阶组件是纯函数,需要保证没有副作用。
- 在进行功能组合时,一般通过增加不相关的props的形式给原有组件传递信息。
- 不要在render方法中使用高阶组件。
- 高阶组件不会传递refs。