setState跟新数据是同步还是异步?
setState跟新数据是异步的。 如何用代码表现出来是异步的。 点击按钮更新数据,然后去打印这个值看一下
setState跟新数据是异步的
class Father extends React.Component{ state = { num:0 } addHandler = () => { this.setState({ num: 100 }) console.log('state中的值',this.state.num) } render() { return ( <div> <button onClick={this.addHandler}>新增</button> <p>显示的值 {this.state.num }</p> </div> ) } } ReactDOM.render( <Father></Father>, document.getElementById('root') )
我们发现
当我们使用setState更新数据时候, 然后立刻去获取更新后的值,我们发现不是我们更新后的值。 而是更新前的值。 这就说明了setState跟新数据是异步的
因此需要注意的点
由于 setState 跟新数据是异步的。 因此 setState 后面的代码不要依赖于setState前面的。
同一个方法多次调用 setState会怎么样
class Father extends React.Component{ state = { num:0 } addHandler = () => { <!-- 第一调用 --> this.setState({ num: this.state.num+1 }) console.log('state中的值', this.state.num) <!-- 第二次调用 --> this.setState({ num: this.state.num + 1 }) console.log('state中的值', this.state.num) } render() { return ( <div> <button onClick={this.addHandler}>新增</button> <p>显示的值 {this.state.num }</p> </div> ) } }
我们的结论
在同一个方法中我们调用了两次setState. 但是最后界面上显示的不是2;0+1+1=2 而是显示的1 也就是说虽然多次调用setState,但是最终只会执行一次。 所以只会触发一次渲染界面。所以界面上显示的是1 由于界面只触发一次,所以render函数也只会触发一次
为什么多次调用setState最终只会触发一次渲染界面
这样做的目的是为了性能的考虑。 比如说你写了一个循环,循环了1000次; 设计的时候如果让setState执行1000次; 这样太浪费性能了。 完全可以让开发者将最后的结果进行展示。 所以React并不会将setState执行1000次 而是只会执行一次。 render函数也只会执行一次。
非要让setState多次执行怎么办?
有没有这样的场景? 第二次的setState需要依赖第一次的setState的结果 举个简单的例子:第一次数字从0变为1,第二次1变为10 这个时候我们怎么办了? 比着急,有解决的办法
setState 推荐语法
setState((state, props) => { 参数state,表示最新的state 参数props,表示最新的props }) 需要的是这种语法也是异步的哈
使用推荐语法实现setState多次执行
class Father extends React.Component{ state = { num:0 } addHandler = () => { <!-- 在这个方法中我们多次调用了setState --> this.setState((state, props) => { // state // props return { num: state.num+1 } }) this.setState((state, props) => { // state // props return { num: state.num + 10 } }) console.log('state中的值', this.state.num) } render() { return ( <div> <button onClick={this.addHandler}>新增</button> <p>显示的值 {this.state.num }</p> </div> ) } }
setState第二个参数的诞生
刚刚我们在前面发现console.log获取的值 不是数据更新的后的值。 而是初始值。我们也说了 由于 setState 跟新数据是异步的。 因此 setState 后面的代码不要依赖于setState前面的。 如果我们想获取 setState更新后的值怎么办了? 这个时候我们就需要使用setState的第二个参数。 setState第二个参数的场景 在状态更新完成(界面完成重新渲染)后立刻执行某一个操作 ps:需要注意的的是不可以不会页面中的dom ps:需要注意的的是不可以不会页面中的dom this.setState( (state, props) => { return {} }, ()=>{ console.log('界面完成重新渲染)后立刻执行某一个操作') } )
setState第二个参数的使用
class Father extends React.Component{ state = { num:0 } addHandler = () => { this.setState( (state, props) => { return { num: state.num + 1 } }, () => { console.log('获取setState跟新后的值', this.state.num) console.log('dom节点',document.getElementById('#name') ) console.log('cont', document.title) } ) } render() { return ( <div> <button onClick={this.addHandler}>新增</button> <p id='name'>显示的值 {this.state.num }</p> </div> ) } } ReactDOM.render( <Father></Father>, document.getElementById('root') )