等待 API 获取完成,然后在 Redux 中定义 const

Wait for API fetch to complete before defining const in Redux

提问人:agehlot 提问时间:1/14/2023 更新时间:1/14/2023 访问量:40

问:

我正在尝试在 react-redux 中渲染带有其属性(选中时)的口袋妖怪页面。

我有一个组件PokemonDetail

export function pokemonDetail (props) {
    const { id } = useParams()
    const moves = Object.values(props.state.entities.moves).map((val) => val.name)
    const thisPokemon = props.state.entities.pokemon[id]
    

    useEffect(() => {
        props.requestSinglePokemon(id)
    }, [id])


    return(
            <section className="pokemon-detail">
                <ul>
                    <figure>
                        <img src={thisPokemon.imageUrl} alt={thisPokemon.name} />
                    </figure>
                    <li><h2>{thisPokemon.name}</h2></li>
                    <li>Type: {thisPokemon.pokeType}</li>
                    <li>Attack: {thisPokemon.attack}</li>
                    <li>Defense: {thisPokemon.defense}</li>
                    <li>Moves: {moves.join(', ')}</li>
                </ul>
            </section>

        )
}

此组件通过 thunk 动作发出抓取口袋妖怪的请求

export const requestSinglePokemon = (id) => (dispatch) => {
    APIUtil.fetchPokemon(id).then(
        (payload) => (dispatch(receiveOnePokemon(payload)))
    )
}

问题是,在请求完成之前,move 对象将为空 {},然后它将填充口袋妖怪、移动和物品。然后,当它尝试最初呈现时,它会抛出一个错误,指出它正在尝试对空白对象使用方法。一个简单的解决方法是简单地编写,但我想知道是否有办法让我的常量在定义之前等待请求完成。if (thisPokemon)... {

JavaScript Redux async-await thunk

评论


答:

0赞 XingZhi Lim 1/14/2023 #1

在不了解 props 如何相互作用或 的确切实现的情况下,我只能为您提供一个解决方法,即定义一个局部变量,该变量对条件渲染做出反应并使用它来。基本上是你用代码做什么,但更容易阅读requestSinglePokemonthisPokemonif (thisPokemon)

基本上,您可以定义一个加载状态,并根据 的真实性呈现加载器。thisPokemon

例如

// simplified example


// ... all of your imports

import {useMemo} from 'react'

function PokemonDetail () {
  // ... all of your code

  // when thisPokemon is falsy, loaded is false
  // when thisPokemon is truthy, loaded is true
  const loaded = useMemo(() => {
    return Boolean(thisPokemon);
  }, [thisPokemon])
  

  return <>
    {!loaded&& {'Data is loading...'}}
    {loaded && <>{/* your JSX */}</>}
  </>
}


更好的解决方案是简单地修改父 props 并将组件作为一个整体进行条件化,因此加载逻辑是在容器而不是组件上完成的。这样,组件就不必关心未定义的条件。PokemonDetailthisPokemon

即在父组件上进行条件渲染