【问题标题】:Unable to set state in React after receiving API call response收到 API 调用响应后无法在 React 中设置状态
【发布时间】:2021-05-07 03:03:49
【问题描述】:

所以,我正在 react 中构建一个多页向导组件。
我正在使用功能组件。 父组件持有状态。 每个“Step”(Step1、Step2等)页面都由Parent组件中的switch语句调用。

我的问题是,在我的 Step2 页面中,我传入了一个“数组”项目并从 API 调用接收到一个“数组”响应,但它未能按照我的预期设置该响应的状态。

这是父组件的状态:

  const [colorLinks, setColorLinks] = useState({
      red: [],
      blue: [],
      green: [],
      cyan: [],
      black: [],
      white: [],
      purple: [],
      gold: [],
      lightgreen: [],
      magenta: [],
      orange: [],
      gray: [],
      sepia: [],
      copper: [],
      pink: [],
      brown: [],
      beige: [],
  })

这是在 Parent 组件中编写的用于异步发出请求的代码,这些代码作为 props 传递给 Step2:

const functionWithPromise = item => { //a function that returns a promise
  return Promise.resolve('ok')
}

const anAsyncFunction = async (item, setColorLinks) => {
        let post = {
          "request": {
            "url": "http://colorendpoints.com/",
            "color": item
          }
        }
        let endpointurl = `http://localhost:8021/&url=http://colorendpoints.com/`;
        let result;
    
        try {
          result = await fetch(endpointurl, {
            method: "POST",
            body: JSON.stringify(post),
            headers: {
              Accept: "application/json",
              "Content-Type": "application/x-www-form-urlencoded"
            }
          })
          console.log('Successfully completed post request!')
          result = await result.json()
          result = result.items[0] // because it arrives as an array with items I need in 0th position
          setColorLinks({
                  red: result.red,
                  blue: result.blue,
                  green: result.green,
                  cyan: result.cyan,
                  black: result.black,
                  white: result.white,
                  purple: result.purple,
                  gold: result.gold,
                  lightgreen: result.lightgreen,
                  magenta: result.magenta,
                  orange: result.orange,
                  gray: result.gray,
                  sepia: result.sepia,
                  copper: result.copper,
                  pink: result.pink,
                  brown: result.brown,
                  beige: result.beige,
          })
          return functionWithPromise(result)
        } catch (e) {
          console.log('Got an error...e')
          console.log()
          return functionWithPromise(e)    
        }
}

const getData = async () => {
  return Promise.all(list.map(item => anAsyncFunction(item)))
}

仍然在父组件中,然后我将上述(getDatacolorLinkssetColorLinks)传递到 Step2,如下所示:

<Step2 
    getData={getData}
    colorLinks={colorLinks}
    setColorLinks={setColorLinks}
/>

我的名单:['color1', 'color2', 'color1', ...]

尽管进行了上述操作,但我无法让 colorLinks 使用传入的响应进行更新。 我可以清楚地看到控制台中的成功响应,但 setColorLinks完全忽略。 我肯定会通过调用getData 得到结果数组,但即使使用 for 循环,它也会认为结果未定义。 如何解决这个问题并使用 API 调用的结果更新状态? 为什么setColorLinks 不更新我的异步映射函数中的状态?

【问题讨论】:

  • 你的代码是catch吗?如果有,e 是什么?
  • 它在getData 中被调用,如下所示:const getData = async () =&gt; { return Promise.all(list.map(item =&gt; anAsyncFunction(item))) }
  • @JakeWorth 是的,它抓住了,e 表示 error
  • 错误是什么?在catch 中尝试console.log(e)

标签: javascript reactjs asynchronous async-await promise


【解决方案1】:

你的问题来自这个函数

const getData = async () => {
  return Promise.all(list.map(item => anAsyncFunction(item)))
}

您在地图中使用 setColorLink,这意味着您多次调用 setColorLink。但是,setState 是一个异步请求 - 您最终会用新的 setState 覆盖每个状态。

我不确定list 是什么,以及这个.map 是干什么用的。如果您需要遍历一组项目并获取它们。你应该这样做。

const getData = async () => {
  const result = await Promise.all(list.map(item => anAsyncFunction(item)))
  setColorLink(result) //<- set state here, not inside Promise.all
}

您的列表是一组颜色,但 colorLink 只是一个颜色对象。 colorLink 是否意味着颜色对象的数组?

【讨论】:

  • 非常感谢!这正是问题所在。
猜你喜欢
  • 1970-01-01
  • 2021-02-23
  • 2019-08-09
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 2022-11-06
  • 2019-09-09
相关资源
最近更新 更多