受控组件和无状态组件
-
- 推荐使用
受控组件
来实现表单. 在受控组件中, 表单数据是有React组件处理 - 如果让表单数据有DOM处理时, 替代方案为使用非受控组件
-
<input type="text" ref={input =>this._name = input} />
如是, 不通过value控制其值,
- 推荐使用
-
受控组件
<input type="text" value={this.state.name} onChange={this.handleNameChange}/>
- 以上handleNameChange获取输入的值
this.setState({ name: event.target.value });
赋值给state, 然后在触发刷新, 对用input的value赋新的值
-
无状态组件
语法简洁, 占内存小(少了class的诸多属性), 无副作用(纯函数), 函数式写法(柯里化)
-
函数式组件: 使用props
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
-
状态组件/类组件的优点:
- 可以使用this
- 拥有局部状态: this.state
- 声明周期钩子
生命周期流程
父子组件嵌套的生命周期, 先初始化父组件, 在父组件的render组件中初始化子组件, 当子组件都创建完成后(都完成了
componentDidMount
方法后) 父组件执行componentDidMount
-
启动过程
father constructor father componentWillMount father render son constructor son componentWillMount son render son componentDidMount father componentDidMount
-
组件更新过程
son componentWillReceiveProps son shouldComponentUpdate 根据返回值 true/false 决定是否继续执行 son componentWillUpdate son render son componentDidUpdate
setState() 执行流程, 生命周期.
利用队列机制管理state, 避免重复的view刷新
replaceState({}) 会完全替代原有的state, setState不会影响未涉及的state
-
如果组件正处于创建或更新组件阶段,则把新的更新放入
dirtyComponents
稍后处理- 故getInitialState,componentWillMount, render,componentWillUpdate 中setState都不会引起updateComponent。但在componentDidMount和componentDidUpdate中则会。
-
主要流程如下
1.enqueueSetState将state放入队列中,并调用enqueueUpdate处理要更新的Component
2.如果组件当前正处于update事务中,则先将Component存入dirtyComponent中。否则调用batchedUpdates处理。
3.batchedUpdates发起一次transaction.perform()事务
-
4.开始执行事务初始化,运行,结束三个阶段
1.初始化:事务初始化阶段没有注册方法,故无方法要执行
2.运行:执行setSate时传入的callback方法,一般不会传callback参数,
3.结束:更新isBatchingUpdates为false,并执行FLUSH_BATCHED_UPDATES这个wrapper中的close方法
FLUSH_BATCHED_UPDATES在close阶段,会循环遍历所有的dirtyComponents,调用updateComponent刷新组件,并执行它的pendingCallbacks, 也就是setState中设置的callback。第二个参数?
我的理解: setState 修改state是异步操作, 意思就是不能立即获取
this.state
修改的值, 当调用了setState后,把本次操作放入队列中, 如果组件未在创建/更新,那么立即执行更新流程, 如果组件在刷新,那么本次更新操作放入稍后执行的队列中等待执行.批处理时会把待处理数组中每一个操作从第一个依次传递给后一个,直到待处理操作为空,把最后的结果设置给state