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:
- Mismatched Initial State Structure
Your reducer's initial state setstrendingto an empty array[], but the API returns an object with aresultsarray inside it. When the page first loads, your component tries to accesstrending.resultson that empty array—this is why you get the "cannot read property map of undefined" error. - Component Definition Inside Render
You're defining theCardcomponent inside therendermethod ofHome. This causes React to re-create theCardcomponent every timeHomere-renders, leading to unexpected state/behavior inconsistencies. - No Loading State Handling
You aren't checking theloadingflag 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.resultsstarts as an empty array instead ofundefined, somapwon'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
trendingalready 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
Cardoutsiderenderprevents React from re-creating it on every state update, which eliminates unexpected re-renders and improves performance.
内容的提问来源于stack exchange,提问作者syc
相关产品推荐
相关产品推荐

