繁体   English   中英

反应 setState 钩子不适用于 useEffect

[英]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>;

如果你想在不渲染的情况下检查加载的值,那么你需要另一个依赖于loadinguseEffect

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM