开发者问题收集

TypeError:无法读取 react-redux 中未定义的属性“map”

2016-07-31
7489

我对 React 和 Redux 还不熟悉,仍然有点困惑。

我的目标是使用 GET 请求在 HTML 中呈现一堆 json 数据。我正在使用 react 和 redux 来管理对象的状态,但是我相信我的问题是数据甚至不存在

所以基本上每当有人请求 URL /courses 时,他/她都会看到 json 中的一堆数据。

我收到组件中的错误

TypeError: Cannot read property 'map' of undefined

这是代码

操作

export function getCourses() {
  return (dispatch) => {

    return fetch('/courses', {
      method: 'get',
      headers: { 'Content-Type', 'application/json' },
    }).then((response) => {
      if (response.ok) {
        return response.json().then((json) => {
          dispatch({
            type: 'GET_COURSES',
            courses: json.courses
          });
        })
      }
    });
  }
}

Reducer

export default function course(state={}, action) {

  switch (action.type) {
    case 'GET_COURSES':
      return Object.assign({}, state, {
        courses: action.courses
      })
    default:
      return state;
  }


}

组件

import React from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';


class Course extends React.Component {



  allCourses() {
    return this.props.courses.map((course) => {
      return(
        <li>{ course.name }</li>
      );

    });
  }

  render() {
    return (
      <div>
        <ul>
          { this.allCourses() }
        </ul>

      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    courses: state.courses
  }
}

export default connect(mapStateToProps)(Course);

索引减速器,我在其中组合所有内容

import { combineReducers } from 'redux';
import course from './course';

export default combineReducers({
  course,
});

配置存储,我在其中存储初始状态和减速器

import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

export default function configureStore(initialState) {
  const store = createStore(
    rootReducer,
    initialState,
    compose(
      applyMiddleware(thunk),
      typeof window == 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
    )
  );

  return store;
}

我相信为什么数据不存在是因为我没有调用操作?任何帮助都将不胜感激。

2个回答

mapStateToProps 将根状态作为参数(您的索引减速器,也是根减速器),而不是您的 course 减速器。据我所知,这是您商店的结构:

-index <- This is the root reducer
  -course

因此,要从该状态获取课程,请在您的组件中:

// state is the state of the root reducer
const mapStateToProps = (state) => {
  return {
    courses: state.course.courses
  }
}

此外,您可以考虑使用空的课程数组初始化 course 减速器的状态,因此如果您必须在触发操作之前呈现组件,则不会收到错误。

const initialState = {
    courses: []
};

export default function course(state= initialState, action) {

    ...

}

最后,您根本没有触发操作,因此您永远不会真正获得课程,我假设您希望在加载 Course 组件后检索它们,为此,您可以在组件中使用 componentDidMount 事件。

首先,您需要将操作映射到组件的属性

// Make sure you import the action
import { getCourses } from './pathToAction';

...

const mapDispatchToProps = (dispatch) => {
  return {
    onGetCourses: () => dispatch(getCourses())
  };
}

// Connect also with the dispatcher
export default connect(masStateToProps, mapDispatchToProps)(Course);

现在调用组件挂载时的 onGetCourses 属性

class Course extends React.Component {

    componentDidMount() {
      this.props.onGetCourses();
    }

    ...

}
Marco Scabbiolo
2016-07-31

这是因为 props 有时可能未定义,所以你必须写这样的条件

allCourses() {
     if(this.props.courses){
    return this.props.courses.map((course) => {
      return(
        <li>{ course.name }</li>
      );
    });
   }
   else {
   return []; 
  }
abhirathore2006
2016-07-31