gpt4 book ai didi

javascript - React - useState 钩子(Hook)第一次和后续设置状态时的奇怪行为

转载 作者:行者123 更新时间:2023-12-03 06:50:12 25 4
gpt4 key购买 nike

考虑这段代码:

const {useState} = React;

function App() {
const [count, setCount] = useState(0);

const onClick = () => {
setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

console.log("onclick");
};

console.log("rendering");

return <button onClick={onClick}> Increment {count} </button>;
}

ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

当运行并单击按钮时,这是它产生的输出:
1
onclick
2
3
rendering
我本来希望输出是
onclick 
1
2
3
rendering
因为我正在使用更新程序功能来访问以前的统计信息,所以默认情况下,状态更新是批处理和异步的。
预期如此,进一步单击按钮确认,并产生以下输出:
onclick 
4
5
6
rendering
我怀疑第一个设置状态在钩子(Hook)的情况下总是同步的,因为如果我将代码更改为:
function App() {
const [count, setCount] = useState(0);

const onClick = () => {
// add this extra set state before any other state updates
setCount(1);
setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

console.log("onclick");
};

console.log("rendering");

return <button onClick={onClick}> Increment {count} </button>;
}
预期的输出是:
onclick 
2
3
4
rendering
我还没有在网上找到任何解释。
这不会像我看到的那样影响任何功能,因为尽管第一次同步执行它仍然异步更新状态,这意味着我无法访问 console.log("onclick"+ count) 中的更新状态
有助于解释为什么它会这样工作。
注意:在 github 上讨论了这个。似乎这是我们作为消费者不应该关心的事情之一。这是一个实现细节。 https://github.com/facebook/react/issues/19697

最佳答案

React 会将所有状态更改合并到一个更新中以减少渲染,因为渲染成本很高,setState调用 log 时不一定会更新。所以你可以log("count="+(count+3))或使用 useEffect .useEffect当状态/ Prop 改变时设置回调;以下片段显示了如何记录 count每次它改变。您可以引用the docs了解更多信息。

const {useState,useEffect} = React;

function App() {
const [count, setCount] = useState(0);

useEffect(()=>{
console.log("effect!count=" + count)
},[count])

const onClick = () => {
setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

setCount((prevCount) => {
console.log(prevCount + 1);
return prevCount + 1;
});

console.log("onclick");
};

console.log("rendering");

return <button onClick={onClick}> Increment {count} </button>;
}

ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

关于javascript - React - useState 钩子(Hook)第一次和后续设置状态时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63586754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com