-
setSate
我们先看几个关于 setState 的 demo,用于黑箱推测原理:1) “ 打印 0 ″——说明 setState 相当于发布订阅中的发布,只是把多个状态变更需求统一放入队列 updateQueue;
"打印 2"——说明存在一个专门用于开启 / 关闭 ** 批量 ** 更新模式的控制器 batchUpdate。基本流程:开启控制器 —— 入队列 (updateQueue 和 callbackQueue) —— 合并 updateQueue 中 state 的变化 —— 根据变化来更改 state —— 执行 callbackQueue —— 关闭控制器;整个流程是同步的。
class Mine extends React.Component {constructor(props){super(props); this.state = {number: 0}; } add = () => {this.setState({number: this.state.number+1}); this.setState({number: this.state.number+2}); console.log(this.state.number);// 打印 0 setTimeout(() => {console.log(this.state.number);// 打印 2 }) } render(){return (<button onClick={this.add}></button>) } }
2) 理解上面流程了,就能理解为什么定时器中的 setState 看起来并不是延迟执行。
因为定时器到期前,整个流程已经跑完了,控制器处于关闭状态,所以就立即更新 state 了;即在 setState 源码中,若控制器开启,则需要入队列;若控制器关闭,则不入队列,立即执行;
this.setState({number: this.state.number+1}); this.setState({number: this.state.number+2}); this.setState({number: this.state.number+3}); setTimeout(()=>{this.setState({number: this.state.number+4}); console.log(this.state);// 打印 7 }, 1000)
总之,setState 有延迟 / 批量更新,是为了节省渲染 DOM 的开销,同时也保留了立即更新的功能
-
ref 的几种用法
1) ref= 字符串
不推荐,难以维护class Calculator extends React.Component {add = () => {let num1 = Number(this.refs.num1.value); let num2 = Number(this.refs.num2.value); this.refs.result.value = num1+num2 } render(){ return ( <div> <input ref="num1" /> + <input ref="num2" /> <button onClick={this.add}\>=</button\> <input ref="result" /> </div> ) } }
2) ref= 函数
不推荐。函数在 DOM 渲染后执行,instance 就是 DOM 元素的实例~~~~class Calculator extends React.Component {add = () => {let num1 = Number(this.num1.value); let num2 = Number(this.num2.value); this.result.value = num1+num2 } render(){ return ( <div> <input ref={instance=>this.num1=instance} /> + <input ref={instance=>this.num2=instance} /> <button onClick={this.add}>=</~~~~button> <input ref={instance=>this.result=instance} /> </div> ) } }
3)React.createRef
推荐写法~~~~class Calculator extends React.Component {constructor() {super(); this.num1 = React.createRef(); this.num2 = React.createRef(); this.result = React.createRef();} add = () => {let num1 = Number(this.num1.current.value); let num2 = Number(this.num2.cu~~~~rrent.value); this.result.current.value = num1 + num2;~~~~ }; render() { return ( <div> <input ref={this.num1} /> + <input ref={this.num2} /> <button onClick={this.add}>=</button> <input ref={this.result} /> </div> ); } }