我可以在与更新状态相同的功能中使用更新状态吗? 在下面的示例中,我得到0。
使用useEffect
,我可以在设置状态后立即访问新状态,但是如果要在函数中访问该怎么办。
作为附带的问题,当状态不直接与返回值连接时,是否可以使用状态?我应该改用道具吗?
function App() {
const [count, setCount] = useState(0)
const handleClick = async () => {
setCount(count => (count + 1));
await new Promise(r => setTimeout(r, 2000));
console.log(count); // I get 0
}
return (
<div>
<Button onClick={handleClick}></Button>
</div>
)
}
答案 0 :(得分:1)
您不能。这就是我使用useReducer的原因。
答案 1 :(得分:1)
不,你不能(或者也许可以,因为我会告诉你一些诡计)。对于功能组件,状态略有不同。当组件渲染时,将创建handleClick函数,并且由于JavaScript的工作方式,它会附加到该特定渲染的“作用域”。即使超时后,它仍然在旧的范围内。
解决此问题的一种方法是使用参考。
function App() {
const [count, setCount] = useState(0)
const countRef = useRef(count)
countRef.current = count
const handleClick = async () => {
setCount(count => (count + 1));
await new Promise(r => setTimeout(r, 2000));
console.log(countRef.current);
}
return (
<div>
<Button onClick={handleClick}></Button>
</div>
)
}
这将在重新渲染组件时更新引用。此更新将更改所有参照,即使是旧范围中的参照。
但是,我使用React的次数很多,并且可以肯定我从来没有被要求在实践中使用它。我会说这是一个坏习惯:即使超时,也不能100%地确定该状态实际上有足够的时间来更新,因此这可能会导致奇怪的错误。您实际上为什么要这样做?例如,您能否将需要新状态的代码放在useEffect中?
关于附带问题:当状态改变时,当需要重新渲染组件时,应使用state。如果您不希望在状态更改时重新渲染组件,则应使用另一种存储数据的方法(例如refs)。