【问题标题】:TypeError: Cannot read property 'map' of undefined using ReactJsTypeError:无法使用 ReactJs 读取未定义的属性“地图”
【发布时间】:2018-09-12 22:32:03
【问题描述】:

我收到“TypeError: Cannot read property 'map' of undefined”。不知道我在哪里出错了。在 React 方面我还是个新手,所以我不知道我是否遗漏了什么。当我尝试调用 this.props.meals.map 时,它给了我错误

export class Dashboard extends React.Component {
  componentDidMount() {
    this.props.dispatch(fetchProtectedData());
    this.props.dispatch(retrieveDailyLogs())
    .then(results => {
        return this.props.dispatch(getDailyLogs(results));
    })
}

getId(id) {
   console.log('test');
   this.props.dispatch(removeDay(id))
   this.props.dispatch(retrieveDailyLogs())
  .then(results => {
    return this.props.dispatch(getDailyLogs(results));
});
}


render() {
    const dailyLogs = this.props.meals.map((day, index) => 
    <li className="card" key={index}>
        <Card handleClick={(id) => this.getId(id)} {...day} />
    </li>
    )
    return (
        <section className="dashboard-container">
            <h1>Dashboard</h1>
            <Link className="log-day-btn" to="/dailylogs">Log Meals</Link>
            <ul className="meal-list">
            {dailyLogs}
            </ul>
        </section>
    );
}
}

const mapStateToProps = state => ({
  meals: state.dailyLogsReducer.dailyLogs
});

export default requiresLogin()(connect(mapStateToProps)(Dashboard));

这是我的减速器,以防万一这可能会有所帮助

import {ADD_DAY, GET_DAILYLOGS, DELETE_DAY} from '../actions/dailyLogs';

const initialState = {
 dailyLogs: [{
    date: null,
    meal1: null,
    meal2: null,
    meal3: null,
    snack: null,
    totalCalories: null,
}]
};

export default function reducer(state = initialState, action) {
 if (action.type === ADD_DAY) {
    return Object.assign({}, state, {
        dailyLogs: [...state.dailyLogs, {
            date: action.date,
            meal1: action.meal1,
            meal2: action.meal2,
            meal3: action.meal3,
            snack: action.snack,
            totalCalories: action.totalCalories
        }]
    });
}
else if(action.type === GET_DAILYLOGS) {
    return Object.assign({}, state, {
            dailyLogs: action.dailyLogs.dailyLogs
    })
}
else if(action.type === DELETE_DAY) {
    return 'STATE';
}
return state;
}

这是我的 combineReducer。它在我的 store.js 中

combineReducers({
    form: formReducer,
    auth: authReducer,
    protectedData: protectedDataReducer,
    dailyLogsReducer
}),

【问题讨论】:

  • 它是说this.props.meals 是未定义的——这只能意味着你在渲染&lt;Dashboard/&gt; 时没有传入任何meals 属性。看不到您在哪里进行检查以进行检查,但没有其他解释。
  • 好吧,我以为我是在底部的 mapStateToProps 下这样做的。看看我的 dailyLogsReducer 会有帮助吗?
  • 抱歉,我错过了@D Graves。恐怕我只涉足过 React,从未使用过 Redux(尽管不久前我已经阅读过它的文档),所以目前这有点过头了。我要说的一件事,刚刚再次快速检查,“reducer”应该是一个函数(它接受一个状态和一个动作并返回一个新状态),所以我不确定你的 dailyLogsReducer 有什么dailyLogs 属性。如果没有,那就可以解释为什么您的 meals 属性未定义。希望比我更有知识的人能够提供帮助!
  • 分享你的reducer,如果你结合其中的几个,你的combine reducer配置肯定会有所帮助。另外,这些数据是否来自异步操作?
  • 你能用 Redux 开发工具以某种方式跟踪你的状态吗?非常好用,可以考虑使用。尝试在此组件中记录您的状态。不要打开一个状态,只需打开整个状态,例如:const mapStateToProps = state =&gt; ({ state }); 然后尝试记录它console.log(this.props.state);

标签: javascript reactjs redux


【解决方案1】:

渲染方法可以在 componentDidMount 之前运行。如果在 render 方法运行时 this.props.meals 尚未定义,您的组件将抛出您看到的错误。

您可以在使用

映射对象之前检查它的存在
this.props.meals && this.props.meals.map( // your code here )

【讨论】:

  • 这就是为什么我问“它是否来自异步操作”:) 赞成。
【解决方案2】:

由于您在 reducer 的 initialState 中将 dailyLogs 声明为一个数组,因此您的地图不应失败,但只有在数据存在时才会向我们显示任何内容。如果数据是通过异步操作获取的,则无法确保在 React 渲染的那一刻,这些数据就已经存在。

所以,我们这里有几点:

确保您不会因为尝试对未定义值使用非未定义操作而收到任何错误:

const dailyLogs = this.props.meals  
console.log("meals =", dailyLogs); // Will help you know what is this value.
dailyLogs ? dailyLogs.map((day, index) => 
  <li className="card" key={index}>
    <Card handleClick={(id) => this.getId(id)} {...day} />
  </li> : // handle the non-mappable value ...
)

在你的 reducer 中,作为一个好习惯,尝试使用 switch case 语句来探索他的好处

switch (action.type) {
   case ADD_DAY: 
       return // ...
   case GET_DAILYLOGS:
       return // ...
   case DELETE_DAY: 
       return // ...
   default: 
       return state;
}

并且在您的 switch 或 if/else 语句返回时,您可以执行以下操作来演化状态,保持他的实际属性(传播):

return { 
    ...state, 
    dailyLogs: [
    // ...
    ]
};

保持您的代码更简洁明了会对您有所帮助。

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 2020-04-20
    • 2020-11-18
    • 2021-07-11
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多