You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Redux中如何等待API请求完成后再定义常量?

解决React-Redux中Pokemon详情页请求完成前的渲染报错问题

方案1:条件性定义计算常量

在定义moves时先判断数据是否加载完成,不存在则返回空数组;同时在组件最外层判断数据状态,未加载完成时显示加载态:

import { useEffect } from 'react';
import { useParams } from 'react-router-dom';

// React组件名需首字母大写(规范要求)
export function PokemonDetail(props) {
  const { id } = useParams();
  const thisPokemon = props.state.entities.pokemon[id];
  const movesState = props.state.entities.moves;

  // 仅当宝可梦数据存在时才处理moves,否则返回空数组
  const moves = thisPokemon ? Object.values(movesState).map(val => val.name) : [];

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

  // 数据未加载完成时显示加载提示
  if (!thisPokemon) {
    return <div>Loading...</div>;
  }

  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>
  );
}

方案2:使用useMemo延迟计算moves

借助React的useMemo钩子,将thisPokemon和movesState设为依赖项,只有当依赖项变化且数据存在时,才执行moves的计算逻辑,避免初始渲染时的无效计算:

import { useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom';

export function PokemonDetail(props) {
  const { id } = useParams();
  const thisPokemon = props.state.entities.pokemon[id];
  const movesState = props.state.entities.moves;

  // 依赖thisPokemon,仅当数据存在时才计算moves
  const moves = useMemo(() => {
    if (!thisPokemon) return [];
    return Object.values(movesState).map(val => val.name);
  }, [thisPokemon, movesState]);

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

  if (!thisPokemon) {
    return <div>Loading...</div>;
  }

  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>
  );
}

方案3:修改Redux初始状态规避空对象问题

如果可以调整Redux的初始状态,把entities.moves的默认值设为空数组而非空对象。这样即使请求未完成,Object.values(movesState)返回的也是空数组,后续map和join操作不会触发报错:

// Redux初始状态示例
const initialState = {
  entities: {
    pokemon: {},
    moves: [] // 将默认值从{}改为[]
  }
};

修改后原组件中的moves定义无需额外判断,初始渲染时moves就是空数组,join(', ')会返回空字符串,不会引发错误。


内容的提问来源于stack exchange,提问作者agehlot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:30:28