"dependencies": {
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"customize-cra": "^1.0.0",
"rc-form": "^2.4.11",
"react": "^17.0.1",
"react-app-rewired": "^2.1.8",
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.1",
"redux": "^4.0.5"
},
import {useState} from "react";
export default function Pre04SetStateSync() {
const [counter, setCounter] = useState(0)
const add = () => {
setCounter(counter + 1)
console.log({counter})
}
return <>
同步SetState
请观察控制台
>
}
export default class Pre04SetStateSync extends React.Component{
state = {
counter:0
}
add = () => {
this.setState({counter:this.state.counter + 1})
console.log('~~this.state.counter',this.state.counter)
}
render() {
return <>
同步SetState
请观察控制台
>
}
}
hooks结构中的setCounter(xxx)相当于class组件写法中setState({counter: xxx})
可以对比控制台看到,这样直接setCounter(setState)后立即输出的counter的是上一次的值,而按钮上显示正确,说明本次更新是异步的(react这样设计是为了批量更新而提高性能),打印时counter还没来得及改变。如果需要set完后立即取到counter的最新值,可以按如下方法实现同步的效果。
注意,只适用于class组件
add = () => {
setTimeout(()=>{
this.setState({counter:this.state.counter + 1})
console.log('~~this.state.counter',this.state.counter)
},0)
}
注意,只适用于class组件
// 原生事件
export default class Pre04SetStateSync extends React.Component {
state = {
counter: 0
}
componentDidMount() {
document.querySelector('#btn').addEventListener('click', this.add)
}
add = () => {
this.setState({counter: this.state.counter + 1})
console.log('~~this.state.counter', this.state.counter)
}
render() {
return <>
同步SetState
请观察控制台
>
}
}
注意,只适用于class组件
export default class Pre04SetStateSync extends React.Component {
state = {
counter: 0
}
add = () => {
this.setState({counter: this.state.counter + 1}, ()=>{
console.log('~~this.state.counter', this.state.counter)
})
}
render() {
return <>
同步SetState
请观察控制台
>
}
}
注意,class组件和hooks都可以
如果将add改为先加1再加2,会发现代码只执行了最后一个加2,加1被忽略了,如:
const add = () => {
setCounter(counter + 1)
setCounter(counter + 2)
}
解决方法是将setState的参数写成函数形式
const add = () => {
setCounter(counter => counter + 1)
setCounter(counter => counter + 2)
}
注意,只适用于hooks
export default function Pre04SetStateSync() {
const [counter, setCounter] = useState(0)
const add = () => {
setCounter(counter + 1)
}
useEffect(() => {
console.log({counter})
}, [counter])
return <>
同步SetState
请观察控制台
>
}