【问题标题】:React useState hook not updating with axios call反应 useState 钩子不使用 axios 调用更新
【发布时间】:2021-10-20 04:18:58
【问题描述】:

我知道这是一个常见问题,因为我在过去的两个小时里都在检查每个答案并试图更新我的状态,但没有任何效果。

我正在从 cms 获取文本,但是在第一次加载时状态未定义并且我的应用程序崩溃了。但是,如果我注释掉该行,加载页面并取消注释该行会显示正确的值。

这是我尝试过的一些代码。

我希望得到的数据

[
  {id:1},
  {id:2},
  {id:3},
  {id:4},
]
import react, {useEffect, useState} from 'react'
import axios from 'axios'

const [carouselTitle, setCarouselTitle] = useState([])

useEffect(() => {
          fetchData();
    }, []);


    const fetchData = async () => {
        await axios('api').then(
            response => {
                console.log(response.data)
                setCarouselTitle(response.data)
                console.log(carouselTitle)
            })
      };
return(
  <h1>{carouselTitle[1].id}</h1>
)

控制台记录数据工作正常,但是当我控制台记录状态时它不起作用。

我尝试的第二种方法

    useEffect(() => {
        const fetchData = async () => {
         const res = await axios('api');
         const carouselTitleAlt = await res.data;
         setCarouselTitle({ carouselTitleAlt });
         console.log(carouselTitleAlt);
         console.log(carouselTitle);
       };
       fetchData();
      }, []);

再次控制台记录 useEffect 中的 const 会显示正确的信息,但记录状态不起作用。

感谢您的回复或显示数据的更好方式。

【问题讨论】:

  • 你在 useEffect 之外尝试过console.log(carouselTitle) 吗?
  • const [carouselTitle, setCarouselTitle] = useState([] - 这是一个错字吗?缺少正确的括号?
  • @selbie 是的,抱歉,这是一个 * 错字可以确认我的代码有正确的括号!好地方寿:)
  • @matt_roki2 的回答对你有帮助吗?

标签: reactjs axios state


【解决方案1】:

setState 是异步的:https://reactjs.org/docs/faq-state.html#why-doesnt-react-update-thisstate-synchronously

这意味着您不能期望在调用setCarouselTitle 之后的行中控制台记录新的状态值。

要记录新值,您可以使用另一个 useEffect,在依赖项数组中使用 carouselTitle,您可以在其中 console.log(carouselTitle)

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

也就是说,你的组件应该正确运行,当状态更新时它会被刷新。

在 JSX 中,您应该检查 carouselTitle 是否未定义(意味着请求失败或仍在等待中):

{carouselTitle && <H1>{carouselTitle[0].id}}

https://reactjs.org/docs/conditional-rendering.html#gatsby-focus-wrapper

【讨论】:

  • 感谢您的回答。是的,这确实 console.log 它但仍然导致应用程序在页面刷新时以cannot read property of id 崩溃。如果它是状态更新,它可以工作,但仍然会遇到同样的问题...... :(
  • 好的,具体的错误是什么?无法读取未定义的属性 ID?您如何尝试使用您获取的数据?
  • 抱歉没有在您的回答中看到 JSX!
  • 您应该在使用前检查 carouselTitle:{carouselTitle && carouselTitle[1].id}。编辑了我的答案。
  • 和我问丹尼尔的问题一样,为什么会这样?
【解决方案2】:

首先,如果将初始数据的空数组传递给 useState,则无法在此处获取该数组中的任何项:

return(
  <h1>{carouselTitle[1].id}</h1>
)

因为组件返回的数组的第一项没有任何内容。我更喜欢你这样做:

return(
  <h1>{carouselTitle.length > 0 && carouselTitle[0].id}</h1>
)

并且还基于thisofficial documentationsetState(以及使用useState()setSomthing())是异步的。

所以状态数据在设置后不会立即显示。

【讨论】:

  • 这已经解决了,谢谢,但是为什么呢?那行代码背后的逻辑是什么?
  • 在您的版本中,您尝试访问一个未定义值的索引,直到请求返回。所以 JavaScript 会抛出一个错误。
  • @matt_roki2 正如我所说,您将一个空数组传递给useState,在第一次渲染中,组件返回一个没有任何内容的数组的第一项
【解决方案3】:

你应该触发 useEffect 来运行 fetch 函数

useEffect(()=>{fetchData();},[carouselTitle])

【讨论】: