是私有的,并且完全受控于当前组件。
虚拟DOM
用于描述真实DOM的js对象
DIFF算法
1 | /../captainweekly/program/resources/editsurvey_bille.pdf |
diff算法的目的;
如何运用在diff算法之上?(做了什么假设降低算法复杂度)
怎么做?(根节点不同类型;相同类型1,元素类型2,组件类型)
高阶组件
装饰器模式的应用
使用场景
- 操作props
- 通过ref访问组件实例
- 组件状态提升
- 用其他元素包装组件
注意事项
- 自定义高阶组件名字,以便调试
- 静态方法需要手动复制
- ref不会传递给被包装组件
- 不要再render中创建高阶组件。(render是一个频繁调用的函数,而组件的创建+加载+删除是高开销操作)
- 与父组件的区别
- 父组件面向UI/DOM
- 高阶组件是逻辑的抽象
通信
组件与服务器通信
加载阶段通信
更新阶段通信
组件间通信
父子组件通信
兄弟组件通信
Context
更多“通信”
使用消息队列来实现组件通信:改变数据的组件发起一个消息,使用数据的组件监听这个消息,并在响应函数中触发 setState 来改变组件状态。本质上,这是观察者模式的实现,我们可以通过引入 EventEmiter 或 Postaljs等消息队列库完成这一过程。
当应用更加复杂时,还可以引入专门的状态管理库实现组件通信和组件状态的管理,例如 Redux 和 MobX 是当前非常受欢迎的两种状态管理库。
组合与继承
State中应该存储什么内容
意义
State代表一个组件UI呈现的最小、完整状态集。组件中所有状态都用于反应UI变化。又可以分为两类
- 渲染组件时用到的数据来源
- 组件UI展现形式的判断依据
判断变量是否可以放在state?
- 是否可以从组件中获取?
- 在整个生命周期中都保持不变?
- 是否可以通过其他状态(state) 或者 属性(props)计算得到?
- 是否在组件render方法中使用?
State 的更新可能是异步的
例如,此代码可能会无法更新计数器:
1 | // Wrong |
要解决这个问题,可以让 setState()
接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
1 | // Correct |
上面使用了箭头函数,不过使用普通的函数也同样可以:
1 | // Correct |
State 的更新会被合并
数据流是向下的
不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。
这就是为什么称 state 为局部的或是封装的的原因。除了拥有并设置了它的组件,其他组件都无法访问。
组件可以选择把它的 state 作为 props 向下传递到它的子组件中(传递的时候是传值还是传值?)
state vs props
都和组件的渲染无关,它们变化都将触发组件重新渲染。
props对使用它的组件来说是只读的,通过父组件传递而来;
state是组件内部自己维护的状态,是可变的。
生命周期
挂载 | 更新 | 卸载 |
---|---|---|
constructor() |
new props/state/forceUpdaterender() |
componentWillUnmount() |
render() |
componentDidUpdate() |
|
componentDidMount() |
挂载
constructor()
getDerivedStateFromProps()
render()
componentDidMount()
更新
只要组件state或props改变,就进入“更新”
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
卸载
componentWillUnmount()