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

React Redux Reducer无法识别JSON数据引发TypeError问题求助

解决React Redux中Cannot read property 'label' of undefined的问题

你遇到的这个报错,根源其实是数据存储的属性不匹配+初始状态类型错误,再加上组件没处理数据未加载的空白期,咱们一步步拆解修复:

1. 先揪出Reducer里的核心问题

看你的Reducer代码:

  • DATA_LOADED action把请求回来的JSON数据存在了remoteArticles里,但你的组件通过mapStateToProps取的是state.rootReducer.articles——这完全是两个不相关的属性!
  • 初始状态里articles被设成了空数组[],但你请求回来的是包含basics节点的对象,数组根本没有.basics属性,这直接触发了报错。

修正Reducer代码

把请求回来的数据存到articles属性里(更符合你的组件逻辑),同时调整初始状态为null(明确表示数据未加载):

import { FOUND_BAD_WORD, DATA_LOADED, ADD_ARTICLE } from '../constants/action-types';
const initialState = {
  articles: null, // 改成null,匹配后续要存储的对象类型
  remoteArticles: [],
  badword: '',
};
export default function reducer(state = initialState, action) {
  if (action.type === ADD_ARTICLE) {
    return { ...state, articles: state.articles.concat(action.payload) };
  }
  if (action.type === FOUND_BAD_WORD) {
    return Object.assign({}, state, { badword: action.payload[0] }); // 简化冗余赋值
  }
  if (action.type === DATA_LOADED) {
    return { ...state, articles: action.payload }; // 把请求数据存到articles属性
  }
  return state;
}

2. 给组件加上加载状态判断

即使修正了Reducer,Redux-Saga完成请求前,articles还是null,直接访问articles.basics依然会报错。所以要在组件里先判断数据是否就绪:

function Hero({ articles }) {
  // 数据未加载时显示加载提示,避免访问undefined属性
  if (!articles) {
    return <div>Loading...</div>;
  }

  return (
    <section className="hero is-dark is-fullheight has-bg-image">
      <div className="hero-head">
        <NavBar />
      </div>
      <div className="hero-body">
        <div className="container">
          <p className="subtitle is-5 has-text-weight-light">I'm a</p>
          <h1 className="title">{articles.basics.label}</h1>
          <h2 className="subtitle">
            {articles.basics.location.region}, {articles.basics.location.country}
          </h2>
          <div>
            <p className="subtitle is-5 has-text-weight-light">{articles.basics.description}</p>
          </div>
          <div className="navbar-item is-6 is-unselectable">{articles.basics.fansite}</div>
          <div className="navbar-item is-6 is-unselectable">{articles.basics.fansiteDev}</div>
        </div>
      </div>
      <div className="hero-foot" style={{ paddingBottom: '20px' }}>
        <div className="columns is-mobile">
          <div className="column" />
          {/* 用可选链操作符,避免profiles为空时报错 */}
          {articles.basics.profiles?.map(value => {
            const id = uniqueId();
            return (
              <div key={id} className="column has-text-centered">
                <a href={value.url} target="blank" className="is-hovered" title={value.network}>
                  <span className="icon is-medium is-">
                    <i className={value.x_icon} />
                  </span>
                </a>
              </div>
            );
          })}
          <div className="column" />
        </div>
      </div>
      <div style={{ position: 'static', color: 'gray', fontSize: '.875rem', }} >
        <ShowBuildAndVersion />
      </div>
    </section>
  );
}
const mapStateToProps = state => {
  return { articles: state.rootReducer.articles };
};
const Aaa = connect(mapStateToProps)(Hero);
export default Aaa;

3. 可选优化方案

如果你想保留remoteArticles的存储方式,只需要把mapStateToProps改成:

const mapStateToProps = state => {
  return { articles: state.rootReducer.remoteArticles };
};

同时把initialState里的remoteArticles设为null,组件里的加载判断逻辑不变即可。

这样修改后,就能彻底解决你遇到的TypeError问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:37:33