TypeError:无法使用 ReactJs 读取未定义的属性“map”
2018-09-12
5935
我收到“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));
这是我的 Reducer,以防万一这可能有帮助
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
}),
2个回答
render 方法 可以 在 componentDidMount 之前运行。如果在 render 方法运行时尚未定义 this.props.meals,您的组件将抛出您看到的错误。
您可以在通过对象进行映射之前检查其是否存在
this.props.meals && this.props.meals.map( // your code here )
David Gonzalez
2018-09-13
由于您在 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: [
// ...
]
};
保持代码更简洁明了将对您有所帮助。
希望它能有所帮助。
Matheus Reis
2018-09-13