Redux store does not have a valid reducer - reactjs

Haven't been able to find anything around here regarding this error:
"Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers."
My reducer
export default function FriendListReducer(state = {friends : []}, action) {
switch (action.type) {
case 'ADD_FRIEND':
return [
{ friends : action.payload.friend }, ...state.friends
]
default:
return state;
}
return state;
}
Combiner
import { combineReducers } from 'redux';
import { FriendListReducer } from './FriendListReducer';
const rootReducer = combineReducers({
friends: FriendListReducer
});
export default rootReducer;
My store config
import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from '../reducers/reducers';
export default function configureStore(initialState = { friends: [] }) {
const logger = createLogger({
collapsed: true,
predicate: () =>
process.env.NODE_ENV === `development`, // eslint-disable-line no-unused-vars
});
const middleware = applyMiddleware(thunkMiddleware, logger);
const store = middleware(createStore)(rootReducer, initialState);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../reducers/reducers', () => {
const nextRootReducer = require('../reducers/reducers').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}

Your import statement is incorrect. Either you use import { Foo } from 'bar' together with export Foo, or use import Foo from 'bar' if you export with export default Foo.
In other words, change either export default function FriendListReducer to export function FriendListReducer, or change the import statement from import { FriendListReducer } to import FriendListReducer.

If the object is empty.
export default combineReducers({
})
This error will show.

../reducers/reducers ? it's a strange naming
Anyway, it seems ../reducers/reducers doesn't return a reducer, if reducers is a directory, put a index.js inside, import each reducer and create a root reducer
import FriendListReducer from "./FriendListReducer"
const rootReducer = combineReducers({
friendList : FriendListReducer
})
export default rootReducer
Important!! you will have state.friendList in your state.
I hope it will help

store.js
FALSE
import { charactersSlice } from "./charactersSlice.js";
TRUE NOT USING {}
import charactersSlice from "./charactersSlice.js";

It looks like your top-level reducer function is using an array as its default value. Redux expects that the very top of your state will be an object, not an array. Try putting the array at a particular key in that object, like { friendList : [] }.

on above your codes
import { FriendListReducer } from './FriendListReducer';
const rootReducer = combineReducers({
friends: FriendListReducer
});
export default rootReducer;
instead of import { FriendListReducer } from './FriendListReducer';
just say import FriendListReducer from './FriendListReducer';
since FriendListReducer was exported with export default FriendListReducer and not export const FriendListReducer

Please check your combine reducer file It's empty......
you have forgot bind reducer here
import {combineReducers, createStore} from 'redux'
import listDataReducer from '../reducers/ListDataReducer'
const rootReducer = combineReducers({
listDataReducer, // Please add your reducer here
});
export default rootReducer;

I also faced the problem.
What I did was instead of:
combineReducers(productReducer, cartReducer)
I did:
combineReducers({ productReducer, cartReducer })
and it worked.
It expects a valid object for the store.

Related

Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers. i am facing this issue

store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers,
Here My store and root reducer file
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import rootReducer from "./rootReducer";
const middlewares = [logger];
const store = createStore(rootReducer);
export default store;
This is the first time I'm working with React and Redux. I haven't been able to find error around it.
the above code is a total redux setup please help why this error coming:
import { combineReducers } from "redux";
import cardReducer from "../Services/profileimages/reducer";
export default combineReducers(cardReducer);
and my reducer file
import initialState from "./initialState";
import * as types from "./actionTypes";
const cardReducer = ({ state = initialState, action }) => {
switch (action.type) {
case types.FIREBASE_GETTING_IMAGES:
return {
cards: action.cards,
};
default:
return state;
}
};
export default cardReducer;
Haven't been able to find anything around here regarding this error:
import initialState from "./initialState";
import * as types from "./actionTypes";
const cardReducer = ({ state = initialState, action }) => {
switch (action.type) {
case types.FIREBASE_GETTING_IMAGES:
return {
cards: action.cards,
};
default:
return state;
}
};
export default cardReducer;
the above code is a total redux setup please help why this error coming
From the API doc combineReducers(reducers), the reducers parameter should be
An object whose values correspond to different reducing functions that need to be combined into one. See the notes below for some rules every passed reducer must follow.
Therefore, the correct usage is:
import { combineReducers } from 'redux';
import cardReducer from './cardReducer';
export default combineReducers({
card: cardReducer,
});
Besides, the cardReducer has the wrong signature. It should be:
const cardReducer = (state = initialState, action) {}

store.getState is not a function Redux-persist

I'm trying to implement Redux-persist on my React Native app. Following the setup docs exactly, I changed my store.js from this:
import { applyMiddleware, createStore } from 'redux';
import * as thunkMiddleware from 'redux-thunk';
import reducers from '../reducers';
let middlewares = [thunkMiddleware.default];
const store = createStore(reducers, applyMiddleware(...middlewares));
export default store;
To this:
import { applyMiddleware, createStore } from 'redux';
import * as thunkMiddleware from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '#react-native-community/async-storage';
import reducers from '../reducers';
const persistConfig = {
key: 'root',
storage: AsyncStorage,
};
const persistedReducer = persistReducer(persistConfig, reducers);
let middlewares = [thunkMiddleware.default];
export default () => {
let store = createStore(persistedReducer, applyMiddleware(...middlewares));
let persistor = persistStore(store);
return { store, persistor };
};
But now, I'm getting the error TypeError: store.getState is not a function (In 'store.getState()', 'store.getState' is undefined).
Note: I've checked out many questions on stackoverflow with the same store.getState error, but they have very specific issues different from my setup.
Edit: Provider implementation (using RNNv2)
import { Navigation } from 'react-native-navigation';
import { Provider } from 'react-redux';
import store from '../../shared/redux/store';
import { registerScreens } from '../view/screens';
import { initialize } from './navigation';
/**
* Register screens and components for react native navigation
*/
registerScreens({ store, Provider });
const app = () => {
Navigation.events().registerAppLaunchedListener(() => {
initialize();
});
};
export default app;
Registerscreens:
const registerComponentWithRedux = (redux: any) => (
name: string,
component: any,
) => {
Navigation.registerComponentWithRedux(
name,
() => component,
redux.Provider,
redux.store,
);
};
export function registerScreens(redux: any) {
registerComponentWithRedux(redux)(screen, screen.default);
...
}
The issue is with the export, you are exporting a function that returns store in a key. So if you update the store reference in register screens it will work.
import returnStoreAndPersistor from '../../shared/redux/store';
const {store} = returnStoreAndPersistor();
registerScreens({ store, Provider });
If u use 'redux-persists' and return{store, persistor} from ../store just try THIS!!!!!
import returnStoreAndPersistor from "../../store";
const { store } = returnStoreAndPersistor()
console.log(store.getState())
For anyone who has this issue & is using Typescript where the only property on "getState()" is "_persist", the problem was for me caused by setting the type of your combined reducers to "any" due to the type error on supplying your store to persistStore:
Type AnyAction is not assignable to type {your action type}
When I fixed the above issue, the getState issue was resolved.
I fixed this by doing this:
const _ = (state: any = 0, _: AnyAction) => state;
const root = combineReducers({
_,
applicationStatusReducer,
...
});
It seems to resolve the issue (albeit in a hacky / not actually resolving the underlying issue kind of way), if you just add an empty reducer with the action type of "AnyAction" to it.
This issue is happening because this export default method instead of doing this you
can do it like this.
export let store = createStore(persistedReducer, applyMiddleware(...middleware));
export let persistor = persistStore(store);
sorry for any inconvenience
const store = createStore(persistedReducer, applyMiddleware(...middlewares));
const persistor = persistStore(store);
export { store, persistor };
and then
import { store, persistor } from '../../shared/redux/store';

Store does not have a valid reducer?

This is first time i'm working with React and Redux. I haven't able to find error around it.
"webpack-internal:///./node_modules/react-error-overlay/lib/index.js:1446 Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers."
This is reducer:
import { combineReducers } from 'redux';
const rootReducer = combineReducers({});
export default rootReducer;
If the object is empty.
const rootReducer = combineReducers({});
This error will show.
add some data in it like:
import { combineReducers } from 'redux';
import foo from '../foo' //this is your reducer
const rootReducer = combineReducers({foo});
export default rootReducer;
reducer example
//reducer/foo.js
export default function foo(state = null, action) {
switch (action.type) {
case 'MY_ACTION_TYPE':
return action.payload
}
return state;
}

React.js Unable to get property 'dispatch' of undefined or null reference

Issue Screen Shot
I am facing 'dispatch' of undefined issue when executing the application.
Whether I need to import any package to work with dispatch in React.js?
ProgramManager.js: This is my component this is where I am using dispatch to call action creator.
import React from 'react';
import { bindActionCreators } from 'redux';
import {connect} from 'react-redux'
import {postsActions,postsSelectors} from '../store/userList/index';
class ProgramManager extends React.Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.fetchPosts({});
}
fetchPosts(params) {
this.context.store.dispatch(postsActions.fetchPosts(params));
}
render() {
return (
<div className="right-container">
....
</div>
) }
}
function mapStatetoProps(state) {
debugger;
return {
//users: state.Users
params: postsSelectors.getParams(state),
posts: postsSelectors.getPosts(state),
};
}
export default connect(mapStatetoProps)(ProgramManager);
Store.js: This is my Redux Root Store file.
import { applyMiddleware, createStore, combineReducers, compose } from 'redux';
import { createEpicMiddleware } from 'redux-observable';
//import { hashHistory } from 'react-router';
import { routerMiddleware } from 'react-router-redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
import rootEpic from './epics';
// const logger = createLogger({ collapsed: true });
const epicMiddleware = createEpicMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
epicMiddleware.run(rootEpic);
export default createStore(
rootReducer,
composeEnhancers(
applyMiddleware(
epicMiddleware,
logger,
// routerMiddleware(hashHistory),
thunk,
)
)
);
epics.js This is my root epic that combines all sub epic files
import { combineEpics } from 'redux-observable';
import { values } from 'lodash';
import * as postsEpics from './userList/epic';
export default combineEpics(
...values(postsEpics)
);
reducer.js This is my root reducer that combines all sub reducers.
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import posts from './userList/reducer';
export default combineReducers({
posts,
routing: routerReducer,
});
epic.js This the sub epic file that actually gets data from the server.
import { keyBy } from 'lodash';
import axios from 'axios';
import querystring from 'querystring';
import { Observable } from 'rxjs/Observable';
import { push } from 'react-router-redux';
import * as actionTypes from './actionType';
import * as postsActions from './actionCreator';
//import * as RequestModel from './request.model';
export function fetchPosts(action$) {
debugger;
alert('fetchPosts');
//RequestModel.entity = "sample";
return action$.ofType(actionTypes.FETCH_COLLECTION)
.map(action => action.payload)
.switchMap(params => {
return Observable.fromPromise(
axios.get(`http://localhost:8081/posts?${querystring.stringify(params)}`)
// axios.get('http://localhost:4040/admin/getTenantUsers')
).map(res => postsActions.fetchPostsSuccess(res.data, params));
});
}
actionCreation.js this is where the disptacher called to get the state data from post
import { keyBy } from 'lodash';
import * as actionTypes from './actionType';
export function fetchPosts(payload) {
debugger;
return { type: actionTypes.FETCH_COLLECTION, payload };
}
export function fetchPostsSuccess(posts, params) {
debugger;
const byId = keyBy(posts, (post) => post.id);
return {type: actionTypes.FETCH_COLLECTION_SUCCESS, payload: {byId, params}};
}
I have never used a context object to dispatch an action.
I think the best way to have an action ready to be dispatched is by using mapDispatchToProps as the second argument of your connect wrapper, it will bring your action as a prop.
import React from 'react';
import { bindActionCreators } from 'redux';
import {connect} from 'react-redux'
import {postsActions,postsSelectors} from '../store/userList/index';
class ProgramManager extends React.Component {
componentDidMount() {
this.props.fetchPosts();
}
render() {
return (
<div className="right-container">
....
</div>
) }
}
function mapStatetoProps(state) {
debugger;
return {
//users: state.Users
params: postsSelectors.getParams(state),
posts: postsSelectors.getPosts(state),
};
}
function mapDispatchToProps() {
return postsActions
}
export default connect(mapStatetoProps, mapDispatchToProps)(ProgramManager);
mapDispatchToProps is usually a function that simply returns a javascript object with your action creators like:
{
fetchPosts: postActions.fetchPosts,
...
}
That's why you can even go more direct (and no need to declare a mapDispatchToProps function):
export default connect(mapStatetoProps, postActions)(ProgramManager);
React-Redux provides dispatch when you connect your components. So you don't have to use the store in the context to dispatch actions. You can simply do this.props.dispatch(actionCreator()) within your connected components.
Note that it only provides dispatch to your component if you do not pass your own mapDispatchToProps. i.e., when you do
connect(mapStateToProps)(Component)
// or
connect()(Component)
// and not
connect(mapStateToProps, mapDispatchToProps)(Component)
If you provide mapStateToProps, however, you are expected to specify the action creators and wrap them around dispatch, so you don't need the dispatch for manual dispatches anymore.

how to initialise all states when press reset button in redux

in my app i'm using redux with redux-thunk.there is on RESET Button, when user click it i want INITIALIZE all redux state instead of window.location.reload().
index.js (reducers index file)
import { combineReducers } from 'redux';
import { reducer as reduxFormReducer } from "redux-form";
import authReducer from './auth_reducer';
import main from './main'
import BookingData from './booking_reducer';
import StepOne from './stepone';
import StepTwo from './stepTwo'
const rootReducer = combineReducers({
form: reduxFormReducer,
auth: authReducer,
Main:main,
StepOneReducer:StepOne,
StepTwoReducer:StepTwo,
BookingData:BookingData,
})
export default rootReducer;
here each value of object contains separate reducer file and each reducer file has number of states
App.js (root file)
import ReactDOM from "react-dom";
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reduxThunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import AppRouter from './routers/AppRouter';
import reducers from './reducers';
const middleware = [
reduxThunk,
];
const store = createStore(reducers, composeWithDevTools(
applyMiddleware(...middleware),
// other store enhancers if any
));
const token = localStorage.getItem('token');
if(token){
store.dispatch({type:AUTH_USER});
}
ReactDOM.render(
<Provider store={store}>
<AppRouter />
</Provider>
, document.getElementById('app'));
so my problem is when press Reset Button it will call action Creator, it will dispatch the action when it comes to the reducer(index reducer) I'm unable reset all state.
i saw this Question also but here i don't want to change my index reducer file structure because I need export both and project logic also get mess.
how can i initialize all redux state when user click Reset Button
If I understand you correctly, then I am doing a similar thing in my apps:
I reset my entire redux state by dispatching a 'reset', or 'initialize' action, and have a case in all reducers for this action, where I set the state to the initial values.
actually i was exporting AppReducer instead of rootReducer
import { combineReducers } from 'redux';
import { reducer as reduxFormReducer } from "redux-form";
import authReducer from './auth_reducer';
import main from './main'
import BookingData from './booking_reducer';
import StepOne from './stepone';
import StepTwo from './stepTwo'
import {RESET} from '../actions/types';
const AppReducer = combineReducers({
form: reduxFormReducer,
auth: authReducer,
Main:main,
StepOneReducer:StepOne,
StepTwoReducer:StepTwo,
BookingData:BookingData,
})
const rootReducer = (state, action) => {
if (action.type === RESET) {
console.log('reset action inside root');
state = undefined
}
return AppReducer(state, action)
}
export default rootReducer;
worked Dan Abramov solution

Resources