我尝试了简单的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的类型是对象,但为什么呢?我应该将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",
答案 0 :(得分:8)
问题是由于rootReducer被"要求" (ES5):
var rootReducer = require('./reducers.js');
如果您通过ES6方法导入它,它将正确保存rootReducer.js'默认自动进入rootReducer:
import rootReducer from './reducers';
我看到你在那个文件中混合了ES5(require)和ES6(import)......我也在混合我的项目,这就是我遇到这个问题的原因。可以在此处找到更多信息:https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.2x2p2dx3m
答案 1 :(得分:4)
state.products
然后从各个reducer函数返回的初始状态自动创建初始状态。可以state.specialPosts
和jokesApi.js
答案 2 :(得分:0)
/* 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;
答案 3 :(得分:0)
我使用VS Code Insiders,有时更改无法正确保存。因此,如果您按照上述所有操作并且错误仍然存在,则转到每个文件并按STRG + S.它为我解决了这个问题。
答案 4 :(得分:0)
创建存储区时,第一个参数必须是表示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()
);
}
答案 5 :(得分:0)
当您看到错误时:
<块引用>未捕获的错误:期望 reducer 是一个函数
这并不一定意味着 reducer
不是函数。如果您遇到此错误,您应该尝试使用仅 reducer
创建商店。像这样:
createStore(reducer)
这可能有效。
就我而言,第二个参数是错误的,因为我没有以正确的顺序调用 compose
和 applyMiddleware
。所以这是一个正确的设置,似乎在我的情况下有效:
export const createDebugStore = () => {
const options: EnhancerOptions = {}
const composeFunc = (typeof window !== 'undefined' && composeWithDevTools(options)) || compose;
const enhancer = composeFunc(applyMiddleware());
return createStore((state: any) => state || {}, enhancer);
}