我收到“ TypeError:无法读取未定义的属性'map'”。不知道我在哪里出错了。关于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
}),
答案 0 :(得分:5)
渲染方法 可以在componentDidMount之前运行。如果在render方法运行时尚未定义this.props.meals,则组件将引发您看到的错误。
您可以使用
在通过对象进行映射之前检查其是否存在。this.props.meals && this.props.meals.map( // your code here )
答案 1 :(得分:1)
由于您将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 ...
)
在您的减速器中,作为一种好习惯,尝试使用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: [
// ...
]
};
保持代码简洁,简洁将对您有帮助。
希望它会有所帮助。