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

在Redux中配置Axios调用:NASA API数据存储与展示问题

Hey there! As someone who’s been where you are—fumbling with Redux after using component state for async calls—I totally get the frustration. Let’s break this down step by step, fixing the data display issue first and then walking through a clean, maintainable structure that fits your NASA API use case.

First, let’s get one key point straight: Redux itself doesn’t handle async logic out of the box. Since you’re using Axios for API calls, you’ll need middleware to manage those async actions. The good news is Redux Toolkit (the official, recommended way to write Redux now) includes this middleware by default, so we’ll use that to simplify things.


Step 1: Implement the Redux Setup for NASA API

1.1 Install Required Dependencies

If you haven’t already, install Redux Toolkit and React-Redux:

npm install @reduxjs/toolkit react-redux

1.2 Create a Redux Slice for NASA Data

Slices are Redux Toolkit’s way of grouping reducers, actions, and async logic in one place. Create a nasaSlice.js file (we’ll organize this properly later):

// src/features/nasa/nasaSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

// Async thunk to fetch the picture of the day
export const fetchPictureOfTheDay = createAsyncThunk(
  'nasa/fetchPictureOfTheDay',
  async (apiKey) => {
    const response = await axios.get(`https://api.nasa.gov/planetary/apod?api_key=${apiKey}`);
    return response.data;
  }
);

const initialState = {
  apodData: null,
  loading: false,
  error: null,
};

const nasaSlice = createSlice({
  name: 'nasa',
  initialState,
  reducers: {}, // No sync actions needed here
  extraReducers: (builder) => {
    builder
      // Handle pending request (loading state)
      .addCase(fetchPictureOfTheDay.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      // Handle successful response
      .addCase(fetchPictureOfTheDay.fulfilled, (state, action) => {
        state.loading = false;
        state.apodData = action.payload;
      })
      // Handle failed request
      .addCase(fetchPictureOfTheDay.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch NASA data';
      });
  },
});

export default nasaSlice.reducer;

1.3 Configure the Redux Store

Create a store file to combine your slices:

// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import nasaReducer from '../features/nasa/nasaSlice';

export const store = configureStore({
  reducer: {
    nasa: nasaReducer, // This key is how we'll access the state later
  },
});

1.4 Wrap Your App with the Redux Provider

In your root component (usually App.js or index.js), wrap everything with Provider so components can access the store:

// src/App.js
import { Provider } from 'react-redux';
import { store } from './app/store';
import PictureOfTheDay from './features/nasa/PictureOfTheDay';

function App() {
  return (
    <Provider store={store}>
      <PictureOfTheDay />
    </Provider>
  );
}

export default App;

1.5 Update Your PictureOfTheDay Component

Now modify your component to pull data from Redux instead of local state:

// src/features/nasa/PictureOfTheDay.js
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchPictureOfTheDay } from './nasaSlice';

// Replace with your actual NASA API key (get one for free at NASA's developer portal)
const NASA_API_KEY = 'YOUR_API_KEY_HERE';

function PictureOfTheDay() {
  // Pull state from Redux
  const { apodData, loading, error } = useSelector((state) => state.nasa);
  const dispatch = useDispatch();

  // Trigger the async fetch when the component mounts
  useEffect(() => {
    dispatch(fetchPictureOfTheDay(NASA_API_KEY));
  }, [dispatch]);

  // Handle loading/error states
  if (loading) return <div>Loading astronomy picture of the day...</div>;
  if (error) return <div>Oops! Error: {error}</div>;
  if (!apodData) return <div>No data available</div>;

  // Render the data once it's loaded
  return (
    <div style={{ maxWidth: '800px', margin: '0 auto', padding: '2rem' }}>
      <h1>{apodData.title}</h1>
      <p className="date">{apodData.date}</p>
      {apodData.media_type === 'image' ? (
        <img 
          src={apodData.url} 
          alt={apodData.title} 
          style={{ width: '100%', borderRadius: '8px' }} 
        />
      ) : (
        <iframe 
          src={apodData.url} 
          title={apodData.title} 
          style={{ width: '100%', height: '400px', borderRadius: '8px' }}
        />
      )}
      <p className="explanation" style={{ marginTop: '1.5rem', lineHeight: '1.6' }}>
        {apodData.explanation}
      </p>
    </div>
  );
}

export default PictureOfTheDay;

For small to medium apps, organizing by feature (instead of type, like "components" or "reducers") is the best practice. Here’s how your structure should look:

src/
├── app/
│   └── store.js       # Root Redux store
└── features/
    └── nasa/          # All NASA-related code lives here
        ├── nasaSlice.js   # Redux logic (actions, reducers, async thunks)
        └── PictureOfTheDay.js # UI component

This keeps everything related to the NASA feature in one place, making it easy to find and maintain.


Common Pitfalls You Might Be Hitting

  • Forgot to wrap your app with Provider: If your component isn’t inside the Provider component, useSelector and useDispatch won’t work.
  • Not handling async states: Redux Toolkit’s createAsyncThunk generates pending/fulfilled/rejected actions—you need to handle these in extraReducers to update loading/error/data states.
  • Incorrect state path in useSelector: Make sure you’re accessing state.nasa.apodData (since we named the reducer nasa in the store).
  • Invalid API key: Double-check that your NASA API key is valid and correctly passed to the thunk.

Final Tip

Install the Redux DevTools Chrome extension—it’s invaluable for debugging. You can see exactly when actions are dispatched, how the state updates, and what payloads are being passed. This will help you quickly spot if your async action is failing or if the state isn’t updating as expected.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:47:34