为什么 setLoading 和 setSecond 在Promise和setimeout中执行会分别出发两次render,而直接调用的话只会触发一次render
注明: 这里去除useEffect执行前的首次渲染
效果如下
代码:
function App() {
const ref = useRef(0)
const [loading, setLoading] = useState(true);
const [second, setSecond] = useState([]);
useEffect(() => {
console.log('useEffectuseEffectuseEffect')
setLoading(true)
/**
* 包含在Promise和setTimeout中
* 执行setLoading和setSecond会分别执行两次渲染
*/
Promise.resolve().then(() => {
console.log('Promise')
setLoading(false)
setSecond([1, 3, 4])
})
// setTimeout(() => {
// setLoading(false)
// setSecond([1, 3, 4])
// }, 1000)
// 执行setLoading和setSecond只执行一次渲染
// setLoading(false)
// setSecond([1, 3, 4])
}, []);
// console.log('mounted ----->', ++ref.current, second)
return (
<div>
{ (function() { console.log('render ----->', ref.current, second) })() }
{ loading && (function(){console.log('loading...')})() }
</div>
);
}
react 的batchUpdate 问题,在非react生命周期内以及合成时间内(比如原声事件监听、Promise回调函数、定时器中),react无法预知行为,无法批量合并更新,class组件也一样,可以讲setState或setxxx 放进
unstable_batchedUpdates(() => {setXXX();setXXX()})
进行批量更新