Redux中mapStateToProps获取JSON对象时出现TypeError问题求助
解决Redux中获取Vitamins数组时的"Cannot read property 'vitamins' of undefined"错误
让我们一步步排查你的问题,找到错误根源并修正:
1. Reducer状态结构不匹配导致的核心错误
你的错误直接出在mapStateToProps里的state.micros.vitamins,这是因为你的reducer状态结构和调用逻辑完全不匹配:
- 你的reducer初始状态是:
const initialState = { micros: [] }; - 当
FETCH_VITAMINS_SUCCESS触发时,你把state.micros直接替换成了action.payload.vitamins(也就是后端返回的vitamins数组):
这意味着return { ...state, micros: action.payload.vitamins };state.micros本身就是vitamins数组,而不是一个包含vitamins属性的对象。所以你再去访问state.micros.vitamins自然会报错——数组根本没有vitamins这个属性。
修正mapStateToProps
改成直接取state.micros,因为它就是你要的vitamins数组:
const mapStateToProps = state => ({ vitamins: state.micros, // 这里直接取state.micros即可 });
2. React组件中状态/属性调用错误
你的组件里有两处明显问题:
- 你在
renderData里试图从this.state.micros读取数据,但实际上你通过mapStateToProps把数据放到了props里,不是组件自身state; - 你解构了
const { vitamins } = this.state.micros,但micros本身就是vitamins数组,完全不需要再解构。
修正组件代码
componentDidMount() { this.props.dispatch(fetchVitamins()); } renderData() { // 直接从props里取vitamins数组 return this.props.vitamins.map((micro, index) => { // 注意:你的后端返回的只有name属性,没有value,所以value用micro.name即可 return ( <option value={micro.name} key={index}>{micro.name}</option> ) }) } render() { return ( <select value={this.props.value}> {this.renderData()} </select> ) } // 修正后的mapStateToProps const mapStateToProps = state => ({ vitamins: state.micros, });
3. 其他需要修正的细节
后端路由代码错误
你的后端路由没有正确返回响应,必须用res.json()把数据发回前端:
router.get('/', function(req, res, next) { res.json({ vitamins: [ { name: "Vitamin B2" } ], minerals: [ { name: "Zinc" } ] }); });
Action中的请求路径不匹配
你的action里请求的是"/users",但后端路由是"/",需要统一路径:
export function fetchVitamins() { return dispatch => { // 把路径改成和后端一致的"/" return fetch("/") .then(res => res.json()) .then(micros => { dispatch(fetchVitaminsSuccess(micros.vitamins)); return micros.vitamins; }) }; }
额外建议
为了避免初始渲染时数组为空导致的map报错,你可以给renderData加个兜底判断:
renderData() { if (!this.props.vitamins || this.props.vitamins.length === 0) { return <option value="">暂无维生素选项</option>; } return this.props.vitamins.map((micro, index) => { return ( <option value={micro.name} key={index}>{micro.name}</option> ) }) }
内容的提问来源于stack exchange,提问作者John White
相关产品推荐
相关产品推荐

