【问题标题】:React+Redux - Uncaught Error: Expected the reducer to be a functionReact+Redux - 未捕获的错误:预计减速器是一个函数
【发布时间】:2016-07-22 12:49:14
【问题描述】:

我尝试了简单的 react、redux、ajax 工作示例并遵循Reddit API tutorial,但我无法创建商店并出现错误:

Uncaught Error: Expected the reducer to be a function.

index.jsx

...

import { createStore, applyMiddleware } from 'redux'
var thunkMiddleware = require('redux-thunk');
var createLogger = require('redux-logger');
var rootReducer = require('./reducers.js');

        const loggerMiddleware = createLogger();

        function configureStore(initialState) {
            return createStore(
                rootReducer,
                initialState,
                applyMiddleware(
                    thunkMiddleware,
                    loggerMiddleware
                )
            )
        }

        const store = configureStore();

...

rootReducer.js

import { combineReducers } from 'redux';

function products(state = {
    isFetching: false,
    didInvalidate: false,
    items: []
}, action) {
    switch (action.type) {
        case 'REQUEST_PRODUCTS':
            return Object.assign({}, state, {
                isFetching: true,
                didInvalidate: false
            })
        case 'RECEIVE_PRODUCTS':
            return Object.assign({}, state, {
                isFetching: false,
                didInvalidate: false,
                items: action.posts,
                lastUpdated: action.receivedAt
            })
        default:
            return state
    }
}

function specialPosts(state = { }, action) {
    switch (action.type) {
        case RECEIVE_SPECPOSTS:
        case REQUEST_SPECPOSTS:
            return Object.assign({}, state, {
                req: true
            })
        default:
            return state
    }
}

const rootReducer = combineReducers({
    products,
    specialPosts
});

export default rootReducer;

rootReducer 的类型是 object,但是为什么呢?我应该将createStore 函数更改为rootReducer.default 吗?

return createStore(
    rootReducer.default,
    initialState,
    applyMiddleware(
        thunkMiddleware,
        loggerMiddleware
     )
)

package.json

"redux-logger": "^2.6.1",
"react-redux": "^4.4.1",
"react-redux-provide": "^5.2.3",
"redux": "^3.3.1",
"redux-thunk": "^2.0.1",

【问题讨论】:

  • @dandavis 错误的 sn-p。我已经编辑过了。
  • 我需要rootReducer var rootReducer = require('./reducers.js').default;

标签: javascript reactjs redux


【解决方案1】:
const rootReducer = combineReducers({
    products,
    specialPosts
});

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

然后从各个 reducer 函数返回的初始状态自动创建初始状态。这些单独的状态可以通过state.productsstate.specialPosts 访问

【讨论】:

  • 也许可以解释一下你的变化?
  • 您可能需要添加更多解释,以便对寻求类似解决方案的其他人有意义。
【解决方案2】:

问题是由于“require”(ES5)导入了rootReducer:

var rootReducer = require('./reducers.js');

如果你通过 ES6 方法导入它,它会正确地将 rootReducer.js 的默认值自动保存到你期望的 rootReducer 中:

import rootReducer from './reducers';

我看到您在该文件中混合了 ES5(要求)和 ES6(导入)...我也在我的项目中混合,这就是我遇到这个问题的原因。更多信息可以在这里找到:https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.2x2p2dx3m

【讨论】:

    【解决方案3】:

    rootReducer

    /* index.js */
    
    import AppReducer from './reducers';
    // import {AppReducer} from './reducers';
    // bugs : must be a root reducer, can not be use as a module
    
    
    
    
    
    
    
    
    
    /* reducers.js */ 
    
    // initial state
    const initialState = {
        angular: 0,
        react: 0,
        vuejs: 0
    };
    
    
    // reducers update state 
    const AppReducers = (state = initialState, action) => {
        switch (action.type) {
            case 'VOTE_ANGULAR':
                console.log("Vote Angular!");
                return (
                    Object.assign(
                        {}, 
                        state, 
                        {
                            angular: state.angular + 1
                        }
                    )
                );
            case 'VOTE_REACT':
                console.log("Vote React!");
                return (
                    Object.assign(
                        {}, 
                        state, 
                        {
                            react: state.react + 1
                        }
                    )
                );
            case 'VOTE_VUEJS':
                console.log("Vote Vue.jsc!");
                return (
                    Object.assign(
                        {}, 
                        state, 
                        {
                            vuejs: state.vuejs + 1
                        }
                    )
                );
            default:
                return state;
        }
    };
    
    export {AppReducers};
    export default AppReducers;
    

    【讨论】:

    • import {AppReducer} from './reducers'; 会出错!
    【解决方案4】:

    我使用 VS Code Insiders,有时无法正确保存更改。因此,如果您遵循上述所有操作并且错误仍然存​​在,请转到每个文件并按 STRG+S。它为我解决了这个问题。

    【讨论】:

      【解决方案5】:

      当您创建商店时,第一个参数必须是表示 reduce(()=>[]) 参数的函数

      错误:

      import {createStore,applyMiddleware} from 'redux';
      
      
      export default function configureStore(initialState) {
        return createStore(
          [],
          {},
          applyMiddleware()
        );
      }
      

      解决方案:

      import {createStore,applyMiddleware} from 'redux';
      
      
      export default function configureStore(initialState) {
        return createStore(
          ()=>[],
          {},
          applyMiddleware()
        );
      }
      

      【讨论】:

        【解决方案6】:

        当你看到错误时:

        未捕获的错误:预计减速器是一个函数

        这并不一定意味着reducer 不是一个函数。如果您遇到此错误,您应该尝试使用reducer 创建商店。像这样:

        createStore(reducer)

        这可能有效。

        就我而言,第二个参数是错误的,因为我没有按正确的顺序调用composeapplyMiddleware。所以这是一个正确的设置,似乎在我的情况下有效:

        
        export const createDebugStore = () => {
            const options: EnhancerOptions = {}
            const composeFunc = (typeof window !== 'undefined' && composeWithDevTools(options)) || compose;
            const enhancer = composeFunc(applyMiddleware());
        
            return createStore((state: any) => state || {}, enhancer);
        }
        
        

        【讨论】:

          【解决方案7】:

          我也遇到了同样的问题,解决了

          const redux = require('redux');
          const store = redux.createStore(reducer);
          

          而我的reducer

          const reducer = (state = initailState, action)=>{
              if(action.type === 'BUY_CAKE'){
          
                  return {...state, numOfCake : state.numOfCake + 1}
              }
              if(action.type === BUY_ICECREAM){
          
                  return {...state, numOfIceCream : state.numOfIceCream + 1}
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-11-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-04
            • 1970-01-01
            • 2020-04-14
            相关资源
            最近更新 更多