Ich habe versucht, einfach zu reagieren, redux, ajax zu arbeiten und folgte dem Reddit API Tutorial , aber ich kann keinen Speicher erstellen und eine Fehlermeldung erhalten:
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 ist ein Objekt, aber warum? Soll ich die createStore
-Funktion in rootReducer.default
ändern?
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",
const rootReducer = combineReducers({
products,
specialPosts
});
const store = createStore( rootReducer, applyMiddleware( thunkMiddleware ));
Der Anfangszustand wird dann automatisch aus den Ausgangszuständen der einzelnen Reduzierfunktionen erstellt. Auf diese einzelnen Zustände kann als state.products
und state.specialPosts
zugegriffen werden.
Das Problem lag darin, dass rootReducer von "required" (ES5) importiert wurde:
var rootReducer = require('./reducers.js');
Wenn Sie es über die ES6-Methode importieren, wird der Standardwert von rootReducer.js automatisch wie erwartet in rootReducer gespeichert:
import rootReducer from './reducers';
Ich sehe, Sie mischen ES5 (Required) und ES6 (Import) in dieser Datei ... Ich habe auch in meinem Projekt gemischt, weshalb ich auf dieses Problem gestoßen bin. Weitere Informationen finden Sie hier: https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.2x2p2dx3m
Ich verwende VS Code Insiders und manchmal werden Änderungen nicht korrekt gespeichert. Wenn Sie also alle oben genannten Punkte befolgt haben und der Fehler immer noch vorhanden ist, gehen Sie zu jeder Datei und drücken Sie STRG + S. Es hat das Problem für mich gelöst.
Wenn Sie das erste Speicherargument erstellen, muss es sich um eine Funktion handeln, die den Parameter verkleinern (()=>[]
) bedeutet
Error:
import {createStore,applyMiddleware} from 'redux';
export default function configureStore(initialState) {
return createStore(
[],
{},
applyMiddleware()
);
}
Lösung:
import {createStore,applyMiddleware} from 'redux';
export default function configureStore(initialState) {
return createStore(
()=>[],
{},
applyMiddleware()
);
}
/* 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;