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 (
<div>
<Button onClick={this.onButtonClick.bind(this)}>點擊</Button>
<div>
這個數字就是啊哈哈哈:{this.state.count}
</div>
</div>
)
}
}
打印結果:
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 (
<div className="page-hospital-container">
<Button onClick={onButtonClick}>點擊</Button>
<div>這個數字就是:{count}</div>
</div>
);
};
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的方式才能獲取到!
個人見解,有什麼不對的地方,歡迎大神評論區留言😄