React + Redux:Uncaught Error:期望reducer成为一个函数

时间:2017-03-13 07:23:13

标签: javascript reactjs redux redux-thunk

我收到了错误消息,但我不确定如何解决它:

Uncaught Error: Expected the reducer to be a function

以下是我的react / redux工作流程的各个部分:

root reducer

import { combineReducers } from 'redux';
import PostsReducer from './reducer_posts';
import StreakReducer from './reducer_streak';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
  entries: PostsReducer,
  form: formReducer,
  streak: StreakReducer
});

export default rootReducer;

动作创建者

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

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

export const FETCH_ENTRIES = 'FETCH_ENTRIES';
export const FETCH_LONGEST = 'FETCH_LONGEST';

const ROOT_URL = 'http://localhost:3000/entries';

export function fetchEntries() {
  const request = axios.get(`${ROOT_URL}`);
  return {
    type: FETCH_ENTRIES,
    payload: request
  };
}


// action creator for returning the longest streak of rejections
export function longestStreak() {
  return function(dispatch) {
    return fetchEntries().then(
      entries => dispatch(findLongestStreak(entries))
    );
  };
}


function findLongestStreak(entries) {
  var longestStreakLength = 10;
  return {
    type: FETCH_LONGEST,
    payload: longestStreakLength
  };
}

条纹减速器

import { FETCH_LONGEST } from '../actions/index';

const INITIAL_STATE = { streak: 0 };

export default function(state = INITIAL_STATE, action) {
  switch(action.type) {
    case FETCH_LONGEST:
      return { ...state, streakInfo: action.payload.data};
    default:
      return state;
  }
}

帖子缩减

import { FETCH_ENTRIES, CREATE_ENTRY } from '../actions/index';

const INITIAL_STATE = { all: [], entry: null };

export default function(state = INITIAL_STATE, action) {
  switch(action.type) {
    case CREATE_ENTRY:
      return {...state, entry: action.payload.data };
    case FETCH_ENTRIES:
      return { ...state, all: action.payload.data };
    default:
      return state;
  }
}

组件

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { longestStreak } from '../actions/index';


class EntriesMetadata extends Component {
  componentWillMount() {
    this.props.longestStreak();
  }

  render() {
    return (
        <div>
      </div>
    );
    }
  }

function mapStateToProps(state) {
  return { streak: state.streak.streakInfo };
}

export default connect(mapStateToProps, { longestStreak })(EntriesMetadata);

我迷失了如何解决这个问题。谁能指出我正确的方向?这是我的第一个redux项目!如果需要任何其他代码段,请告诉我。

修改

这是我的github回购:https://github.com/pchung39/courage

4 个答案:

答案 0 :(得分:1)

请尝试如下: 为减速器功能添加名称:

export default function PostsReducer(state = INITIAL_STATE, action) {
  switch(action.type) {
    case CREATE_ENTRY

: 使用StreakReducer做同样的事情。 我检查了自己的项目,这是我和你的解决方案之间的唯一区别。

答案 1 :(得分:1)

您需要修复actions/index.js内的代码。它目前重新导入Redurs然后尝试创建商店,不应该存在。由于两个reducer都导入了这个文件,它们最终会触发循环依赖。

清理动作代码后,您需要修复其他代码错误。

答案 2 :(得分:1)

我无法理解为什么你在你的行动中创建商店,你已经在你的index.js中做过了吗?

如果您从操作文件中注释掉商店代码,它应该可以正常工作。看起来像一个循环的依赖。

使用更改在您的存储库上创建PR。检查一下。

如果您遇到任何问题,请告诉我。这是PR link

答案 3 :(得分:0)

您忘记了mapDispatchToProps。您应该使用mapDispatchToProps传递您的操作,然后从props(this.props.actions.longestStreak())访问它之后

const mapDispatchToProps = (dispatch) =>({
    actions: bindActionCreators(longestStreak, dispatch)
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(EntriesMetadata);