it-roy-ru.com

React + Redux - Uncaught Error: ожидаемая функция редуктора

Я попробовал простой пример реакции, редукса, ajax и следовал учебник Reddit API , но я не могу создать хранилище и получить ошибку:

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;

enter image description here

Тип rootReducer является объектом, но почему? Должен ли я изменить функцию 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",
11
Matt
const rootReducer = combineReducers({
    products,
    specialPosts
});

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

Затем начальное состояние создается автоматически из начальных состояний, возвращаемых отдельными функциями редуктора. Эти отдельные состояния могут быть доступны как state.products и state.specialPosts

3
Tom

Проблема была в том, что rootReducer был импортирован командой «require» (ES5):

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

8
Mike Lambert

Я использую VS Code Insiders, и иногда изменения не сохраняются правильно. Поэтому, если вы выполнили все вышеперечисленное и ошибка все еще существует, перейдите к каждому файлу и нажмите STRG + S. Это решило проблему для меня.

0
Matthis Kohli

При создании хранилища первым аргументом должна быть функция, означающая параметр limit (()=>[])

Ошибка:

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()
  );
}
0
KARTHIKEYAN.A

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;
0
user8202629