【问题标题】:useState keeps initial state after defining it in useEffectuseState 在 useEffect 中定义后保持初始状态
【发布时间】:2022-01-19 11:24:59
【问题描述】:

我有一个从 API 获取一些数据的异步函数。因为我需要这些数据来正确加载我的组件,所以我决定在 useEffect 中获取数据,然后将其存储在 useState 中,这样就可以了。但是,如果我尝试通过控制台记录它,它只会显示其初始状态,这在技术上意味着它仍未设置或控制台日志在分配 useState 之前运行。

提前感谢您的帮助。

const [categories, setCategories] = useState([])

useEffect(() => {
    fetchListProductCats().then(function(result){
        setCategories(result.data)
    })
    console.log(categories) // returns -> []
    
}, []);

if(!categories.length){
    return "loading"
}

【问题讨论】:

  • 你自己说的,它是异步的,你记录的时候数据还没有设置。
  • 是的,我就是这么想的,但是我要如何等待异步函数完成呢?
  • 好吧,在这种情况下,不仅你的函数是异步的,而且在 React 中设置状态也是异步的。因此,您将需要使用另一种效果来等待对categories 的更改(如几个答案中所述)

标签: javascript reactjs use-effect use-state


【解决方案1】:

async 使用 Promise 函数,确保你知道它的含义。

此代码中的 console.log 行始终在 Promise 解决之前运行。

如果你想观察类别的变化,使用另一个useEffect

useEffect(() => {
  console.log(categories);
}, [categories]);

【讨论】:

  • 感谢您的回答,但如果我按照您的建议执行操作,console.log 会运行两次,第一次运行时会像以前一样记录一个空数组,第二次会记录填充后的数组大批。我不确定,因为我对 React 还很陌生。在性能方面不是很差吗?我的意思是,如果它是一个功能,它可能不会产生明显的效果,但是如果我的项目规模更大,它肯定会导致延迟?
  • @Luke_KS 有一个official document 解释了这一点。实际上第二个参数决定了这个钩子的运行性能。通常,每次重新渲染时,只会对数组中的值进行几次比较。它是安全的,并且比重新渲染时其他步骤消耗的性能要低得多。
【解决方案2】:

您的状态已经使用您希望其显示类别及其初始值的数据进行了更新,因为您已经渲染了 useEffect 没有依赖关系。 并且在更新之前得到了安慰。 尝试使用以下代码 sn-ps 记录。

useEffect(() => {
    console.log(categories)
}, [categories]);

【讨论】:

    【解决方案3】:

    React setState 是异步的。调用函数后不会立即更新。它将首先通过重新渲染过程来更新用户界面。重新渲染完成后,useEffect 挂钩中提供的函数将被调用。

    useEffect(()=>{
      console.log(categories)
    }, [categories]) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      • 2019-08-18
      • 2022-01-19
      • 2019-09-06
      • 1970-01-01
      相关资源
      最近更新 更多