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

React+Redux天气搜索项目:Axios请求数据及Action Payload传递与404处理

Hey there! Let's tackle your two questions about your React-Redux weather app—these are super common scenarios when working with async APIs, so I’ve got you covered.

1. Passing Axios Response Data to Redux Action Payload

Since Axios calls are asynchronous, you’ll need to use redux-thunk (a middleware that lets you write async action creators) to handle the API request and pass the data to your Redux store. Here’s a step-by-step breakdown:

Step 1: Set up redux-thunk (if you haven’t already)

First, make sure you’ve installed it:

npm install redux-thunk

Then configure your Redux store to use the middleware:

// store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import weatherReducer from './reducer';

const store = createStore(weatherReducer, applyMiddleware(thunk));
export default store;

Step 2: Write an async action creator in action.js

Use async/await (or .then() if you prefer) to make the Axios call, then dispatch a success action with the response data as the payload:

// action.js
import axios from 'axios';

// Action types
export const FETCH_WEATHER_SUCCESS = 'FETCH_WEATHER_SUCCESS';
export const FETCH_WEATHER_ERROR = 'FETCH_WEATHER_ERROR';

// Async action creator
export const fetchWeather = (cityName) => async (dispatch) => {
  try {
    // Replace with your actual weather API endpoint
    const response = await axios.get(`https://api.yourweatherprovider.com/data?city=${cityName}`);
    
    // Dispatch success action with the API data as payload
    dispatch({
      type: FETCH_WEATHER_SUCCESS,
      payload: response.data // This is the data you want to store in Redux
    });
  } catch (error) {
    // We’ll handle errors here for your second question
    dispatch({
      type: FETCH_WEATHER_ERROR,
      payload: error.response?.data?.message || 'Oops, that city doesn’t exist!'
    });
  }
};

Step 3: Update your reducer to handle the payload

Your reducer will take the payload from the success action and update the Redux state:

// reducer.js
import { FETCH_WEATHER_SUCCESS, FETCH_WEATHER_ERROR } from './action';

const initialState = {
  weatherData: null,
  error: null
};

const weatherReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_WEATHER_SUCCESS:
      return {
        ...state,
        weatherData: action.payload,
        error: null // Clear any previous errors
      };
    case FETCH_WEATHER_ERROR:
      return {
        ...state,
        error: action.payload
      };
    default:
      return state;
  }
};

export default weatherReducer;
2. Showing a Modal When the API Returns 404 (City Not Found)

You don’t need to rely on component lifecycle methods for this—instead, use Redux state to control when the modal appears. Here’s how:

Step 1: Add an action to clear errors

First, add a simple action to reset the error state when the user closes the modal:

// action.js
export const CLEAR_WEATHER_ERROR = 'CLEAR_WEATHER_ERROR';

export const clearWeatherError = () => ({
  type: CLEAR_WEATHER_ERROR
});

Step 2: Update the reducer to handle clearing errors

Add a case to your reducer to reset the error state:

// reducer.js
case CLEAR_WEATHER_ERROR:
  return {
    ...state,
    error: null
  };

Step 3: Render the modal based on Redux error state

In your search component (or a global modal component), use useSelector to check for an error, and conditionally render the modal. Use useDispatch to trigger the clear error action when the user closes it:

// WeatherSearch.js
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchWeather, clearWeatherError } from './action';

const WeatherSearch = () => {
  const [city, setCity] = useState('');
  const dispatch = useDispatch();
  const { error } = useSelector(state => state.weather); // Adjust to match your store structure

  const handleSearch = () => {
    if (city.trim()) {
      dispatch(fetchWeather(city));
    }
  };

  const handleCloseModal = () => {
    dispatch(clearWeatherError());
  };

  return (
    <div className="weather-search">
      <input
        type="text"
        value={city}
        onChange={(e) => setCity(e.target.value)}
        placeholder="Enter city name"
      />
      <button onClick={handleSearch}>Search Weather</button>

      {/* Error Modal */}
      {error && (
        <div className="modal-overlay">
          <div className="modal">
            <h3>Error</h3>
            <p>{error}</p>
            <button onClick={handleCloseModal}>Close</button>
          </div>
        </div>
      )}
    </div>
  );
};

export default WeatherSearch;

Quick Notes:

  • For styling the modal, you can write your own CSS (add a semi-transparent overlay, center the modal, etc.) or use a UI library like Material-UI or React Bootstrap for pre-built components.
  • If you’re using class components instead of function components, you’ll use connect to map state and dispatch to props, and check for the error in componentDidUpdate if needed—but hooks are much cleaner for this use case.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:12:43