React 基础巩固(二十二)——setState()函数
setState 的三种不同用法
import React, { Component } from "react";
export class App extends Component {
constructor() {
super();
this.state = {
message: "outman",
counter: 0,
};
}
changeText() {
this.setState(
{
message: "outman change",
},
() => {
console.log("+++++", this.state.message);
}
);
console.log("------", this.state.message);
}
increment() {}
render() {
const { message, counter } = this.state;
return (
<div>
<h2>message:{message}</h2>
<button onClick={(e) => this.changeText()}>修改文本</button>
<h2>当前计数:{counter}</h2>
<button onClick={(e) => this.increment()}>counter + 1</button>
</div>
);
}
}
export default App;
setState 为什么设计成异步?
- setState 设计为异步,可以显著的提升性能
- 如果每次调用 setState 都进行一次更新,那么意味着 render 函数会被频繁调用,界面重新渲染,这样效率非常低
- 最好的办法应该是获取到多个更新之后,进行批量更新
- 如果同步更新了 state,但是还没有执行 render 函数,那么 state 和 props 不能保持同步
- state 和 props 不能保持一致性,会在开发中产生很多问题
import React, { Component } from "react";
function Hello(props) {
return <h2>{props.message}</h2>;
}
export class App extends Component {
constructor() {
super();
this.state = {
message: "outman",
counter: 0,
};
}
componentDidMount() {
}
changeText() {
this.setState({
message: "outman change text",
});
console.log(this.state.message);
}
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 { message, counter } = this.state;
return (
<div>
<h2>message:{message}</h2>
<button onClick={(e) => this.changeText()}>修改文本</button>
<h2>当前计数:{counter}</h2>
<button onClick={(e) => this.increment()}>counter + 1</button>
<Hello message={message} />
</div>
);
}
}
export default App;
setState 一定是异步的吗?
在 React18 之前
- 在组件生命周期或 React 合成事件中,setState 是异步
- 在 setTimeout 或者原生 dom 事件中,setState 是同步
在 React18 之后
import React, { Component } from "react";
import { flushSync } from "react-dom";
function Hello(props) {
return <h2>{props.message}</h2>;
}
export class App extends Component {
constructor() {
super();
this.state = {
message: "outman",
counter: 0,
};
}
componentDidMount() {
}
changeText() {
setTimeout(() => {
flushSync(() => {
this.setState({
message: "同步操作",
});
});
console.log(this.state.message);
}, 0);
}
increment() {}
render() {
console.log("render函数被执行");
const { message, counter } = this.state;
return (
<div>
<h2>message:{message}</h2>
<button onClick={(e) => this.changeText()}>修改文本</button>
<h2>当前计数:{counter}</h2>
<button onClick={(e) => this.increment()}>counter + 1</button>
<Hello message={message} />
</div>
);
}
}
export default App;