[英]React setState hook not working with useEffect
我有以下代码。 这个想法是为模拟组件创建一个简单的加载
const [loading, setLoading] = useState(false)
function mockLoading () {
setLoading(true)
console.log('1', loading)
setTimeout(() => {
setLoading(false)
console.log('2', loading)
}, 3000)
}
useEffect(() => {
mockLoading()
}, []);
但由于某种原因,setLoading 不起作用。 Console.log 1 和 2 都是假的
有几件事。 一个问题是,当您设置 state 时,state 不会立即更新。 因此,您的第一个 console.log 将看到旧的 state。 不仅如此,当你的效果被调用和mockLoading
被调用时,它只会看到它被调用时存在的 state 的实例。 因此mockLoading
永远不会看到对变量的任何更改。 这就是效果具有依赖性的原因。 这样,当依赖项更新时,您会看到它。 但考虑到您的代码的结构,我认为这里没有依赖项会有所帮助。 我对您的最终目标不是 100% 清楚,但是要根据您提交的代码完成您想要的,您需要使用useRef
而不是useState
。 useRef
给你一个 object ,它的值总是最新的。 看:
const loadingRef = useRef(false)
function mockLoading () {
loadingRef.current = true;
console.log('1', loadingRef.current)
setTimeout(() => {
loadingRef.current = false;
console.log('2', loadingRef.current)
}, 3000)
}
useEffect(() => {
mockLoading()
}, []);
除非您绝对需要,否则通常不赞成使用 refs。 尝试重构您的代码以依赖于loading
您的useEffect
调用。 但请记住,如果您的mockLoading
在调用时总是更新loading
,您可能会以无限循环告终。 如果尚未设置为您想要的值,请尝试仅更新loading
。 如果您的最终目标是在 3 秒后更新loading
,请尝试以下操作:
const [loading,setLoading] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoading(true);
},3000);
},[]);
return <span>{loading ? 'Loading is true!' : 'Loading is false!'}</span>;
如果你想在不渲染的情况下检查加载的值,那么你需要另一个依赖于loading
的useEffect
:
const [loading,setLoading] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoading(true);
},3000);
},[]);
useEffect(() => {
console.log(loading);
},[loading]);
return <span>{loading ? 'Loading is true!' : 'Loading is false!'}</span>;
希望这可以帮助。
在useEffect
声明您的handler
并在外部登录
const [loading, setLoading] = useState(false)
useEffect(() => {
function mockLoading () {
setLoading(true)
console.log('1', loading)
setTimeout(() => {
setLoading(false)
console.log('2', loading)
}, 3000)
}
mockLoading()
}, []);
console.log(loading)
此外,您应该在unmount
时清除timeout
useEffect(() =>{
const timeout = setTimeout(() =>{}, 0)
return clearTimeout(timeout)
},[])
在 React 中设置 state 是异步的,因此您不会在创建 state 后立即看到更改。 要跟踪 state 更改,您需要使用效果挂钩:
const [loading, setLoading] = useState(false);
function mockLoading() {
setLoading(true);
console.log("1", loading);
setTimeout(() => {
setLoading(false);
console.log("2", loading);
}, 3000);
}
useEffect(() => {
mockLoading();
}, []);
// Display the current loading state
useEffect(() => {
console.log("loading", loading);
}, [loading]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.