React setState、useState到底是同步的,还是异步的?
setState语法
用法1:
this.setState({
// 数据更新
})
用法2:
this.setState((state, props) => {
// 当前组件的state
// 父级的state
}, () => {
// 数据更新之后
})
useState语法
用法1:
const [num, setNum] = useState(0);
...
setNum(1);
用法2:
const [num, setNum] = useState(0);
...
setNum(() => {
// 数据操作
});
setState是同步还是异步?
看一下下面的代码:
import React from 'react';
import { Button } from 'antd-mobile';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
onButtonClick() {
setTimeout(() => {
this.setState({
count: 1
})
console.log('count00000', this.state.count);
})
console.log('count111111', this.state.count);
setTimeout(() => {
console.log('count222222', this.state.count);
})
}
render() {
return (
这个数字就是啊哈哈哈:{this.state.count}
)
}
}
setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
合成事件:就是react 在组件中的onClick等都是属于它自定义的合成事件。
原生事件:比如通过addeventListener添加的,dom中的原生事件。
原生事件举例:
state = {
count:0
};
componentDidMount() {
document.body.addEventListener('click', this.changeVal, false);
}
changeVal = () => {
this.setState({
number: 1
})
console.log(this.state.count)
}
useState是同步还是异步?
看一下下面代码:
import React, { useState } from 'react';
import { Button } from 'antd-mobile';
import './index.scss';
const HospitalInfo = () => {
const [count, setCount] = useState(0);
const onButtonClick = () => {
setTimeout(() => {
setCount(1);
console.log('count0000', count)
})
console.log('count111', count)
setTimeout(() => {
console.log('count222', count)
})
}
return (
这个数字就是:{count}
);
};
export default HospitalInfo;
然后,我们发现都没有获取到最新值,说明useState是异步的!
那如何获取最新值呢?
const [count, setCount] = useState(0);
const countRef = useRef(count);
countRef.current = count;
const onButtonClick = () => {
setTimeout(() => {
setCount(1);
console.log('count0000', count)
})
console.log('count--Ref11', countRef)
console.log('count111', count)
setTimeout(() => {
console.log('count222', count)
console.log('count--Ref22', countRef)
})
}
我们发现在Hooks最近中如果想要获取到最新值,需要在异步+Ref的方式才能获取到!
个人见解,有什么不对的地方,欢迎大神评论区留言