【发布时间】:2021-07-20 07:35:05
【问题描述】:
我一直在学习 React,并且玩得很开心。为了练习使用钩子和上下文 API,我创建了一个非常简单的 Pokemon 应用程序,它从(非常棒的)PokéAPI 获取数据。我似乎无法解决的问题是如何通过从第一次获取数据中检索到的 url 获取数据来初始化我的上下文。这当然是一个糟糕的解释,但我下面的代码澄清了。
我已经将 <App /> 组件包装在 <ContextProvider /> 中,如下所示:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App';
import { ContextProvider } from './Context'
ReactDOM.render(
<ContextProvider>
<App />
</ContextProvider>,
document.getElementById('root')
);
然后直接跳转到我的 Context.js 文件,我正在获取应用程序首次加载时所需的数据:
import React, { useState, useEffect } from 'react'
import fetchSprite from './utils/fetchSprite'
const Context = React.createContext()
function ContextProvider({ children }) {
const [ allPokemon, setPokemon ] = useState([])
console.log(allPokemon)
useEffect(() => {
const fetchData = async () => {
const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=25")
const pokemon = await response.json()
/* Do ANOTHER async operation here */
))
setPokemon(pokemon.results)
}
fetchData()
}, [])
return (
<Context.Provider value={{ allPokemon }}>
{children}
</Context.Provider>
)
}
export { ContextProvider, Context }
解析作为响应提供的 JSON 后,pokemon.results 是一个对象数组,其中每个对象包含一个 name 和 url 属性。 我正在尝试对每个对象使用 url 进行额外的 fetch 调用,这样我还可以存储一个包含指向 PNG 图像的链接的字符串。 同样,在代码中显示这一点将使更有意义:
import React, { useState, useEffect } from 'react'
import fetchSprite from './utils/fetchSprite'
const Context = React.createContext()
function ContextProvider({ children }) {
const [ allPokemon, setPokemon ] = useState([])
useEffect(() => {
const fetchData = async () => {
const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=25")
const pokemon = await response.json()
const pokeData = pokemon.results.map(obj => (
{
...obj,
sprite: fetchSprite(obj.url)
}
))
setPokemon(pokeData)
}
fetchData()
}, [])
return (
<Context.Provider value={{allPokemon}}>
{children}
</Context.Provider>
)
}
export { ContextProvider, Context }
上面,我采用了我将传递给setPokemon 的相同数组,并且基本上复制了数组,但数组中的每个对象都有一个附加属性sprite。
我的fetchSprite.js 文件如下所示:
async function fetchSprite(url) {
const res = await fetch(url)
const data = await res.json()
const result = data.sprites.front_default
return result
}
export default fetchSprite
我不知道如何解决我的 fetchSprite 函数 inside 在我对 .map() 的调用中返回的 Promise。当数组记录到控制台时,我有一个履行的承诺,但不知道如何访问结果:
Screenshot of array with fulfilled promises, logged to the console
我怎样才能让我的.map() 函数在返回添加到数组的对象之前等待每个承诺解决?我尝试了所有类型的异步组合,例如将 .map() 内部的匿名函数设为异步函数,并将 await 用于 sprite 属性。 UI 中产生的问题是我读取 PNG url 的 img 标签已损坏。这让我很生气——非常感谢任何和所有的帮助!!!
【问题讨论】:
-
const pokeData = await Promise.all(pokemon.results.map(....))
-
我仍然得到一个对象数组,其中每个对象的
sprite属性是Promise {<fulfilled>: "...somePokemon.png"}:( -
嘘!!!使用
await Promise.all(...)并在map中创建我的匿名函数@ 异步函数有效。谢谢! -
您可能想post your solution as an answer,而不是作为问题的编辑。
标签: javascript reactjs promise fetch react-context