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

Redux reducer对象payload访问:解决weather.data.map未定义报错

问题分析与解决方案

你的报错根源在于Reducer初始状态和后续返回的状态结构不匹配:一开始你把state初始化为空数组[],但后来改成返回包含data和meta的对象。组件初始化时,this.props.weather是数组,数组没有data属性,所以weather.data会是undefined,调用.map()自然会抛出"cannot read property map of undefined"错误。

下面提供两种解决方案,优先推荐第二种(更符合多城市数据的存储需求):

方案一:修正当前的对象结构状态

如果你想继续使用{ data: [], meta: '' }的对象结构,需要先统一初始状态的格式:

  1. 调整Reducer的初始状态

    import { FETCH_WEATHER } from "../actions/index";
    // 初始状态改为和后续返回一致的对象结构
    export function WeatherReducer(state = { data: [], meta: '' }, action) {
      switch (action.type) {
        case FETCH_WEATHER:
          // 注意要展开state.data而不是state本身,保持结构一致性
          return { 
            data: [action.payload.data, ...state.data], 
            meta: action.meta.city 
          };
        default:
          return state;
      }
    }
    

    这样组件初始化时,this.props.weather.data是一个空数组,.map()可以安全调用。

    ⚠️ 注意:这个方案里meta只会存储最后一次搜索的城市名,如果你需要每个天气条目对应自己的城市名,这个结构不适用,推荐方案二。

方案二:让每个天气条目携带自己的城市名(更合理)

因为你需要每个城市的天气数据都关联对应的城市名称,更好的做法是把城市名合并到每个天气数据对象中,保持state为数组结构(符合Redux存储列表数据的习惯,也和你最初的可运行代码结构更接近):

  1. 修改Reducer

    import { FETCH_WEATHER } from "../actions/index";
    export function WeatherReducer(state = [], action) {
      switch (action.type) {
        case FETCH_WEATHER:
          // 将城市名和天气数据合并成一个对象,添加到数组开头
          const cityWeather = {
            city: action.meta.city,
            ...action.payload.data
          };
          return [cityWeather, ...state];
        default:
          return state;
      }
    }
    
  2. 调整组件代码
    改回使用this.props.weather.map,并在renderWeather中直接访问城市名:

    renderWeather = cityData => {
      const conditions = cityData.forecast.simpleforecast.forecastday[0].conditions;
      const fHigh = cityData.forecast.simpleforecast.forecastday[0].high.fahrenheit;
      return (
        <tr>
          <td>{cityData.city}</td>
          <td>{conditions}</td>
          <td>{fHigh}</td>
        </tr>
      );
    };
    
    render() {
      return (
        <table className="table table-hover">
          <thead>
            <tr>
              <th>City</th>
              <th>Conditions</th>
              <th>High (F)</th>
              <th>Humidity</th>
            </tr>
          </thead>
          <tbody>{this.props.weather.map(this.renderWeather)}</tbody>
        </table>
      );
    }
    

这样修改后,每个天气条目都自带对应的城市名,不会出现覆盖问题,同时初始状态是空数组,.map()可以安全调用,完美解决你的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:51:04