我有以下代码。这个想法是为模拟组件创建一个简单的加载
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均为假
答案 0 :(得分:4)
在handler
中声明您的useEffect
,然后在外部登录
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)
此外,您还应该清洁timeout
上的unmount
useEffect(() =>{
const timeout = setTimeout(() =>{}, 0)
return clearTimeout(timeout)
},[])
答案 1 :(得分:2)
几件事。一个问题是,当您设置状态时,状态不会立即更新。因此,您的第一个console.log将看到旧状态。不仅如此,而且在调用效果并调用mockLoading
时,它将仅看到在调用状态时存在的状态实例。因此,mockLoading
永远不会看到对变量的任何更改。这就是为什么效果具有依赖性的原因。这样,当依赖项更新时,您将看到它。但是,我认为在此依赖于代码结构不会对您有所帮助。我的最终目标不是100%明确,但是要根据提交的代码完成所需的工作,您将需要useRef
而不是useState
。 useRef
为您提供了一个始终是当前值的对象。参见:
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()
}, []);
除非您绝对需要,否则通常不使用引用。尝试在您的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>;
如果您想检查加载的值而不渲染它,那么您将需要另一个useEffect
并依赖于loading
:
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>;
希望这会有所帮助。
答案 2 :(得分:1)
在React中设置状态是异步的,因此在进行更改后,您将不会立即看到状态更改。要跟踪状态更改,您需要使用效果挂钩:
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]);