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

React中请求与数据展示异常问题(Axios、React、Redux)

Hey there, let's break down what's going on here and fix this issue step by step!

Root Causes of the Problem

Let's start with why you're seeing those weird behaviors:

  1. Mismatched Initial State Structure
    Your reducer's initial state sets trending to an empty array [], but the API returns an object with a results array inside it. When the page first loads, your component tries to access trending.results on that empty array—this is why you get the "cannot read property map of undefined" error.
  2. Component Definition Inside Render
    You're defining the Card component inside the render method of Home. This causes React to re-create the Card component every time Home re-renders, leading to unexpected state/behavior inconsistencies.
  3. No Loading State Handling
    You aren't checking the loading flag before trying to render the data, so your component attempts to map over data that hasn't loaded yet on initial page refresh.

Step-by-Step Fixes

1. Fix the Reducer's Initial State

Update your reducer to match the structure of the API response, so trending.results is always an array (even before the API call finishes):

import { GET_TRENDING } from "../types";
const initialState = {
  trending: { results: [] }, // Match API response structure
  loading: true,
};
export default function trendingReducer(state = initialState, action) {
  switch (action.type) {
    case GET_TRENDING:
      return {
        ...state,
        trending: action.payload,
        loading: false,
      };
    default:
      return state;
  }
}

2. Move the Card Component Outside Render

Define Card outside the Home component to avoid unnecessary re-creations, and pass trending as a prop to make it self-contained:

// Define Card outside Home to prevent re-mounts on every render
const Card = ({ trending }) => (
  <Panel bordered header='Card title'>
    {trending.results.map((i) => (
      <React.Fragment key={i.id}>
        <h6>{i.title}</h6>
      </React.Fragment>
    ))}
  </Panel>
);

class Home extends Component {
  componentDidMount() {
    this.props.getTrending();
  }

  render() {
    const { trending, loading } = this.props.trending;
    console.log(trending);

    // Show loading state while data fetches
    if (loading) {
      return <div>Loading trending movies...</div>;
    }

    return (
      <div className='Home'>
        <FlexboxGrid justify='center'>
          <Card trending={trending} />
        </FlexboxGrid>
      </div>
    );
  }
}

export default connect(
  (state) => {
    return {
      trending: state.trending,
    };
  },
  { getTrending }
)(Home);

Why This Fixes Your Weird Behaviors

  • Initial Page Refresh: Now trending.results starts as an empty array instead of undefined, so map won't throw errors while the API call is in flight. The loading state also gives users feedback instead of a broken UI.
  • Hot Reload vs Refresh: Hot reload preserves your app's state from the previous session, so trending already had the API data when you reloaded. A full page reset wipes state, which is why the initial bug only showed up there.
  • Component Stability: Moving Card outside render prevents React from re-creating it on every state update, which eliminates unexpected re-renders and improves performance.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:22:46