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

sin*_*Gob 2 javascript reactjs redux

我是React和Redux的新手,仍然有点困惑。

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

因此,基本上,每当有人请求URL / courses时,他/她都将在json中看到大量数据。

我在组件中收到错误

TypeError:无法读取未定义的属性“ map”

这是代码

行动

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
          });
        })
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

减速器

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

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


}
Run Code Online (Sandbox Code Playgroud)

零件

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);
Run Code Online (Sandbox Code Playgroud)

索引减少器,我将所有内容组合在一起

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

export default combineReducers({
  course,
});
Run Code Online (Sandbox Code Playgroud)

配置Store,在其中存储初始状态和化简器

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;
}
Run Code Online (Sandbox Code Playgroud)

我相信为什么没有数据是因为我没有打电话给我?任何帮助,将不胜感激。

Mar*_*olo 6

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

-index <- This is the root reducer
  -course
Run Code Online (Sandbox Code Playgroud)

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

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

另外,您可能会考虑course使用空的课程数组来初始化reducer 的状态,因此,如果必须在触发操作之前渲染组件,则不会收到错误。

const initialState = {
    courses: []
};

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

    ...

}
Run Code Online (Sandbox Code Playgroud)

最后,您根本不会执行任何操作,因此您永远不会真正获得这些课程,我假设您希望在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);
Run Code Online (Sandbox Code Playgroud)

现在onGetCourses在安装组件时调用属性

class Course extends React.Component {

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

    ...

}
Run Code Online (Sandbox Code Playgroud)