this.setState 的三种使用方式

发布于:2025-06-11 ⋅ 阅读:(31) ⋅ 点赞:(0)

setState 是异步的

3种使用方式

import React, { Component } from 'react'

export class App extends Component {
	constructor(props) {
		super(props)
	
		this.state = {
			msg: 'Hello World',
			counter: 0
		}
	}

	changeTet() {
		`1.1、基本使用(原理是:Object.assign(源state,新state))。`
		// this.setState({
		//   msg: '你好,李银河'
		// })
	
	
	
		` 1.2、setState 可以传入一个回调函数
				好处:可以拿到之前的state 和 props。`
		// this.setState((state, props) => {
		//   console.log('state=', state)
		//   console.log('props=', props)
		//   return {
		//     msg: '你好,李银河2'
		//   }
		// })
	
	
	
	    ` 1.3、setState 在React的事件处理中,是一个异步调用
	            如果,希望在数据更新之后(数据合并),立即获取到新的数据,
	            那么,可以在setState中传入第二个参数:callback。`
	    // this.setState({
	    //     msg: '你好啊,李银河'
	    // })
	    // console.log('this.state.msg=', this.state.msg); // this.state.msg= Hello World
	
		this.setState(
			{
				msg: '你好啊,李银河'
			},
			() => {
				console.log('this.state.msg=', this.state.msg) // this.state.msg= 你好啊,李银河
			}
		)
		console.log('this.state.msg=', this.state.msg) // this.state.msg= Hello World
	}

	increment() {}

	render() {
		const { msg, counter } = this.state
	
		return (
			<div>
				<h2>msg: {msg}</h2>
				<button onClick={e => this.changeTet()}>修改文本</button>
			
				<h2>当前计数:{counter}</h2>
				<button onClick={e => this.increment()}>counter+1</button>
			</div>
		)
	} // end-render
}

export default App

说明


react18之前   
	在生命周期函数、 React合成事(就是你在react中自己写的方法们)中,setState是异步的
	在SetTimeout、原生DOM事件中,setState是同步的

-----------------------------------------------------------------------------
export class App extends Component {
	constructor(props) {
		super(props)
		
		this.state = {
			msg: 'Hello World',
			counter: 0
		}
	}

changeTet() {
	// React18 之前,setTimeout 中的 this.setState() 是同步的,执行完一行再执行下一行
	// 但是
	// React18 之后,setTimeout 中的 this.setState() 也是异步的了
	// setTimeout(() => {
	//   this.setState({ msg: '你好啊,李银河' })
	//   console.log('msg=', this.state.msg) // React18之前,这里打印的是:你好啊,李银河(此项目react的版本大于18)
	// }, 0)

	// 如果,你还想实现 react18之前的同步处理的效果,可以使用 `flushSync`
	setTimeout(() => {
		` flushSync 函数里面的 this.setState() 也是批处理哦,即:
		  多个 this.setState() 会被合并为一个,最终只会执行一次(批处理),意味着render()函数也只会执行一次。`
		flushSync(() => {
			this.setState({ msg: '你好啊,李银河' })
			console.log('msg=', this.state.msg) // Hello World
		})
		console.log('msg=', this.state.msg) // 这里打印的就是:你好啊,李银河
	}, 0)
}


	` this.setState(),是异步执行的
	       多个 this.setState() 会被合并为一个,最终只会执行一次,意味着render()函数也只会执行一次
	       你看render()里面的console.log,只打印了一次,
	       而且,这几个 this.setState() 里面的 this.state.counter的值都是 0,
	       并不是你想的,
		       第一次执行 this.setState() 时候,this.state.counter的值是0,
		       第二次执行 this.setState() 时候,this.state.counter的值是1,
		       第三次执行 this.setState() 时候,this.state.counter的值是2,`
	// increment() {
	//   this.setState({	
	//     counter: this.state.counter + 1
	//   })
	//   this.setState({
	//     counter: this.state.counter + 1
	//   })
	//   this.setState({
	//     counter: this.state.counter + 1
	//   })
	// }

-----------------------------------------------------------------------------

	` this.setState(),是异步执行的,
	      多个 this.setState() 会被合并为一个,最终只会执行一次,意味着render()函数也只会执行一次
	      你看render()里面的console.log,只打印了一次,
	      但是,这样写,
	        第一次执行 this.setState() 时候,state.counter的值是0,
	        第二次执行 this.setState() 时候,state.counter的值是1,
	        第三次执行 this.setState() 时候,state.counter的值是2,
	        执行完第三个 this.setState() 后,state.counter的值就成 3 了。`
	increment() {
		this.setState(state => {
			return {
				counter: state.counter + 1
			}
		})
		
		this.setState(state => {
			return {
				counter: state.counter + 1
			}
		})
		
		this.setState(state => {
			return {
				counter: state.counter + 1
			}
		})
	}

-----------------------------------------------------------------------------

	render() {
		console.log('render被执行了')
		const { msg, counter } = this.state
		return (
			<div>
				<h2>msg: {msg}</h2>
				<button onClick={e => this.changeTet()}>修改文本</button>
				
				<h2>当前计数:{counter}</h2>
				<button onClick={e => this.increment()}>counter+1</button>
			</div>
		)
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到