最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

总结React中的setState

来源:懂视网 责编:小采 时间:2020-11-03 18:21:55
文档

总结React中的setState

总结React中的setState:react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步。1.先来回顾一下react组件中改变state的几种方式:import React, { Component } from 'react'class Index extends Component {
推荐度:
导读总结React中的setState:react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步。1.先来回顾一下react组件中改变state的几种方式:import React, { Component } from 'react'class Index extends Component {

react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步。

1.先来回顾一下react组件中改变state的几种方式:

import React, { Component } from 'react'class Index extends Component {
 state={
 count:1
 }
 test1 = () => { // 通过回调函数的形式
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('test1 setState()之后',this.state.count);
 }
 test2 = () => { // 通过对象的方式(注意:此方法多次设置会合并且只调用一次!)
 this.setState({
 count:this.state.count+1
 });
 console.log('test2 setState()之后',this.state.count);
 }
 test3 = () => { // 不能直接修改state的值,此方法强烈不建议!!!因为不会触发重新render
 this.state.count += 1;
 }
 test4 = () => { // 在第二个callback拿到更新后的state
 this.setState({
 count:this.state.count+1
 },()=>{// 在状态更新且页面更新(render)后执行
 console.log('test4 setState()之后',this.state.count);
 });
 }
 render() {
 console.log('render'); 
 return ( 
 <p>
 <h1>currentState:{this.state.count}</h1>
 <button onClick={this.test1}>测试1</button>
 <button onClick={this.test2}>测试2</button>
 <button onClick={this.test3} style={{color:'red'}}>测试3</button>
 <button onClick={this.test4}>测试4</button>
 </p> )
 }
}
export default Index;

2.setState()更新状态是异步还是同步:

需要判断执行setState的位置

同步:在react控制的回调函数中:生命周期钩子/react事件监听回调

import React, { Component } from 'react'class Index extends Component {
 state={
 count:1
 } /* 
 react事件监听回调中,setState()是异步状态 */
 update1 = () => {
 console.log('update1 setState()之前',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('update1 setState()之后',this.state.count);
 } /* 
 react生命周期钩子中,setState()是异步更新状态 */
 componentDidMount() {
 console.log('componentDidMount setState()之前',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('componentDidMount setState()之后',this.state.count);
 }
 
 render() {
 console.log('render'); 
 return ( 
 <p>
 <h1>currentState:{this.state.count}</h1>
 <button onClick={this.update1}>测试1</button>
 <button onClick={this.update2}>测试2</button>
 </p> )
 }
}
export default Index;

异步:非react控制的异步回调函数中:定时器回调/原生事件监听回调/Promise

import React, { Component } from 'react'class Index extends Component {
 state={
 count:1
 } /* 
 定时器回调 */
 update1 = () => {
 setTimeout(()=>{
 console.log('setTimeout setState()之前',this.state.count);//1
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('setTimeout setState()之后',this.state.count);//2 
 });
 } /* 
 原生事件回调 */
 update2 = () => {
 const h1 = this.refs.count;
 h1.onclick = () => {
 console.log('onClick setState()之前',this.state.count);//1
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('onClick setState()之后',this.state.count);//2 
 }
 } /* 
 Promise回调 */
 update3 = () => {
 Promise.resolve().then(value=>{
 console.log('Promise setState()之前',this.state.count);//1
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('Promise setState()之后',this.state.count);//2 
 });
 }
 
 render() {
 console.log('render'); return ( 
 <p>
 <h1 ref='count'>currentState:{this.state.count}</h1>
 <button onClick={this.update1}>测试1</button>
 <button onClick={this.update2}>测试2</button>
 <button onClick={this.update3}>测试3</button>
 </p> )
 }
}
export default Index;

3.setState()多次调用的问题:

异步的setState()

(1)多次调用,处理方法:

setState({}):合并更新一次状态,只调用一次render()更新界面,多次调用会合并为一个,后面的值会覆盖前面的值。

setState(fn):更新多次状态,只调用一次render()更新界面,多次调用不会合并为一个,后面的值会覆盖前面的值。

import React, { Component } from 'react'class Index extends Component {
 state={
 count:1
 }
 update1 = () => {
 console.log('update1 setState()之前',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('update1 setState()之后',this.state.count);
 console.log('update1 setState()之前2',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('update1 setState()之后2',this.state.count);
 }
 update2 = () => {
 console.log('update2 setState()之前',this.state.count); 
 this.setState({
 count:this.state.count+1
 });
 console.log('update2 setState()之后',this.state.count);
 console.log('update2 setState()之前2',this.state.count); 
 this.setState({
 count:this.state.count+1
 });
 console.log('update2 setState()之后2',this.state.count);
 }
 update3 = () => {
 console.log('update3 setState()之前',this.state.count); 
 this.setState({
 count:this.state.count+1
 });
 console.log('update3 setState()之后',this.state.count);
 console.log('update3 setState()之前2',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));// 这里需要注意setState传参为函数模式时,state会确保拿到的是最新的值
 console.log('update3 setState()之后2',this.state.count);
 }
 update4 = () => {
 console.log('update4 setState()之前',this.state.count); 
 this.setState((state,props)=>({
 count:state.count+1
 }));
 console.log('update4 setState()之后',this.state.count);
 console.log('update4 setState()之前2',this.state.count); 
 this.setState({
 count:this.state.count+1
 });// 这里需要注意的是如果setState传参为对象且在最后,那么会与之前的setState合并
 console.log('update4 setState()之后2',this.state.count);
 }
 render() {
 console.log('render'); return ( 
 <p>
 <h1>currentState:{this.state.count}</h1>
 <button onClick={this.update1}>测试1</button>
 <button onClick={this.update2}>测试2</button>
 <button onClick={this.update3}>测试3</button>
 <button onClick={this.update4}>测试4</button>
 </p> )
 }
}
export default Index;

(2)如何得到setState异步更新后的状态数据:

在setState()的callback回调函数中

4.react中常见的setState面试题(setState执行顺序)

import React, { Component } from 'react'// setState执行顺序class Index extends Component {
 state={
 count:0
 }
 componentDidMount() { this.setState({count:this.state.count+1}); 
 this.setState({count:this.state.count+1});
 console.log(this.state.count);// 2 => 0
 this.setState(state=>({count:state.count+1})); 
 this.setState(state=>({count:state.count+1}));
 console.log(this.state.count);// 3 => 0
 setTimeout(() => { 
 this.setState({count:this.state.count+1});
 console.log('setTimeout',this.state.count);// 10 => 6
 this.setState({count:this.state.count+1});
 console.log('setTimeout',this.state.count);// 12 => 7 
 });
 Promise.resolve().then(value=>{ 
 this.setState({count:this.state.count+1});
 console.log('Promise',this.state.count);// 6 => 4
 this.setState({count:this.state.count+1});
 console.log('Promise',this.state.count);// 8 => 5 
 });
 }
 render() {
 console.log('render',this.state.count);// 1 => 0 // 4 => 3 // 5 => 4 // 7 => 5 // 9 => 6 // 11 => 7
 return ( <p>
 <h1>currentState:{this.state.count}</h1>
 <button onClick={this.update1}>测试1</button>
 <button onClick={this.update2}>测试2</button>
 <button onClick={this.update3}>测试3</button>
 <button onClick={this.update4}>测试4</button>
 </p> )
 }
}
export default Index;

总结:react中setState()更新状态的2种写法

1)setState(updater,[callback])

updater:为返回stateChange对象的函数:(state,props)=>stateChange,接收的state和props都保证为最新的

2)setState(stateChange,[callback])

stateChange为对象,callback是可选的回调函数,在状态更新且界面更新后才执行

注意:

对象是函数方式的简写方式

如果新状态不依赖于原状态,则使用对象方式;

如果新状态依赖于原状态,则使用函数方式;

如果需要在setState()后获取最新的状态数据,在第二个callback函数中获取

本文来自 js教程 栏目,欢迎学习!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

总结React中的setState

总结React中的setState:react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步。1.先来回顾一下react组件中改变state的几种方式:import React, { Component } from 'react'class Index extends Component {
推荐度:
标签: rea 总结 React
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top