reactjs store reducer not correctly implemented - reactjs

I got in my reactjs app this error:
Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.
my store looks like this:
import {applyMiddleware, combineReducers, createStore} from "redux";
import thunk from "redux-thunk";
const store = createStore(
combineReducers({}),
applyMiddleware(thunk)
);
export default store;
how should it look like correctly?

You will get this error until you add a reducer to combineReducers see below example.
Counter reducer '/reducers/counter'
export default (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
};
Store
import {applyMiddleware, combineReducers, createStore} from "redux";
import thunk from "redux-thunk";
import counter from '/reducers/counter';
const store = createStore(
combineReducers({counter}),
applyMiddleware(thunk)
);
export default store;

If you are not going to use reducer decomposition, then why are you using combineReducers? Simply define a function like the following to be your sole reducer and pass it to createStore().
(state = {}, action) => {
switch (action.type) {
default:
return state
}
}
Or simply the following if you just want it to work:
(state = {}, action) => state

Related

react native Error: Actions must be plain objects. Instead, the actual type was: 'string'. You may need to add middleware

am using React redux in react native but facing this error. i have followed many solutions but no one worked for me, hers is more detail about my actions and reduces and store
action.js
export const AddNow =()=>{
return "ADD_NUM"
}
export const DelNow =()=>{
return "DEL_NUM"
}
in reducer folder -> MyBook.js
const initialState = 30;
const MyBook = (state = initialState, action) => {
switch (action.type) {
case "ADD_NUM":
return initialState +1;
case "DEL_NUM":
return initialState -1;
}
return state;
};
export default MyBook
in redcures folder index.js
import MyBook from "./MyBook";
import {combineReducers} from 'redux';
const rootreducers=combineReducers({ cartIMyBooktems})
export default rootreducers;
in store ->index.js
import {createStore,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import rootreducers from '../reducers/index';
export default store = createStore(rootreducers, applyMiddleware(thunk));
in my app.js
import { AddNow , DelNow} from "../../actions";
import {useDispatch} from 'react-redux'
const dispatch = useDispatch();
<CustomBTN
onPress={()=>{dispatch(AddNow) }}
/>
i created this and followed one video tutorial but its not working for me but working for him. can anyone please help me? am beginner
The error says it all.
Your dispatch action is dispatching a string
export const AddNow =()=>{
return "ADD_NUM" //this action dispatches a string (returns a string)
}
this is causing "actual type was string"
It tells you, it is expecting a plain object. A plain object with a type property is also expected in your reducers
///
switch (action.type)
///
It is expecting a plain object with type property.
update your action.js to
action.js
export const AddNow =()=>{
return {
type: "ADD_NUM"
}
}
export const DelNow =()=> {
return {
type: "DEL_NUM"
}
}
now both your actions are returning plain objects, with a type property, as expected by redux dispatch and your reducers
also, since AddNow and DelNow are functions, they should be camelCase.
addNow, delNow
With regards to your book state always being 31.
in your reducers, you are always using the initial value as the modified value. The reducers recieve the current state as as the first parameter state which is defualted to initialState
update your reducers to use the state parameter
const initialState = 30;
const MyBook = (state = initialState, action) => {
switch (action.type) {
case "ADD_NUM":
return state +1; //update initialState to state
case "DEL_NUM":
return state -1; //update initialState to state
}
return state;
};
export default MyBook

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 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;
}

Redux store changes connected component props without corresponding action being dispatched

I have a very weird issue, I have redux store and a react component connected to it with connect() function. I am storing a list of user roles coming from my backend in redux. For this I have two different reducers, userRoleReducer and initialUserRolesReducer. I use the first one to handle changes into the roles in the UI before applying the changes with an API call, and the second one is being used to have the initial roles stored separately after backend responses. The issue I am having, is that both of the reducers are changing, even though only the first one is actually being updated by dispatching an action (Sorry if my use of terms is incorrect). Below are the reducers and action dispatchers.
Reducers:
export function userRolesForUsersRequestSuccess(state = {userRoles: []}, action) {
switch(action.type) {
case 'USER_ROLES_FOR_USERS_REQUEST_SUCCESS':
return action.userRoleDataForUsers;
default:
return state;
}
}
export function initialUserRolesForUsersRequestSuccess(state = {userRoles: []}, action) {
switch (action.type) {
case 'INITIAL_USER_ROLES_FOR_USERS_REQUEST_SUCCESS':
return action.initialUserRoleData;
default:
return state;
}
}
These are the action dispatchers, the first one is called from the connected component, and and after backend response. The second one is called only after the backend response.
export function setUserRolesForUsersRequestSuccess(userRoleDataForUsers) {
return {
type: 'USER_ROLES_FOR_USERS_REQUEST_SUCCESS',
userRoleDataForUsers
};
}
export function setInitialUserRolesForUsersRequestSuccess(initialUserRoleData) {
return {
type: 'INITIAL_USER_ROLES_FOR_USERS_REQUEST_SUCCESS',
initialUserRoleData
};
}
I haven't found anything similar to this from anywhere, so I guess this isn't a common problem, and that's why a good guess is that the issue is in my code. But every other reducer I use are working just fine, and believe me, I have tried to change and check everything I can to make these two work normally as well.
Any help is wanted to track the issue down!
EDIT: The code I use to create the store, not sure if it helps.
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './rootReducer';
import createHistory from 'history/createBrowserHistory';
const composeEnhancers = typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const history = createHistory();
const middleware = routerMiddleware(history);
const initialState = {};
const store = createStore(
rootReducer,
initialState,
composeEnhancers(
applyMiddleware(middleware, thunk))
);
EDIT 2. rootReducer.js file, reducers are combined here.
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import {
userRoleForMeRequestSuccess,
userRolesForUsersRequestSuccess,
userRoleRequestPending,
userPermissionChangeGetResponseMessage,
initialUserRolesForUsersRequestSuccess } from './Common/userRoleReducer';
const appReducer = combineReducers({
userRoleForMeRequestSuccess,
userRolesForUsersRequestSuccess,
userRoleRequestPending,
userPermissionChangeGetResponseMessage,
initialUserRolesForUsersRequestSuccess,
router: routerReducer
});
const rootReducer = (state, action) => {
if (action.type === LOGIN_LOGOUT_REQUEST_SUCCESS) {
state = undefined;
}
return appReducer(state, action);
};
export default rootReducer;
EDIT 3. After I dug more deeply into this problem, I made an observation that if I just pass completely different data for the first reducer, its data stays intact and doesn't change when the other one changes. So could there be some kind of issue in passing exactly the same data as the first new state after the reducers initial state, and that mixes the reducers somehow to always mirror each other?

State is empty in reducer

I working on a react-redux webapp and until now, all action were related to ajax requests, so I'm using redux thunk and axios.
Now, I'm working in a component that would create a list from objects called 'tasks'. This should be very straight forward: the action calls send the task object and the reducer add it in an array inside the 'tasks' state.
The issue is that when called the reducer always rewrite the the tasks object array. Doing a console.log at the beginning of the reducer call I see the state is always empty.
Here is the code:
import {DROP_TASK} from '../actions/types'
export default function (state = {}, action) {
switch (action.type){
case(DROP_TASK):
console.log("state", state); // here is shows object{}
console.log('tasks', state.tasks);
if(state.tasks === undefined || state.tasks === null ) {
return {...state, list: [action.payload]}
}
return {...state, list: [...state.tasks.list, action.payload]};
default:
return state
}
}
at the createStore at the index.js
I'm doing:
const createStoreWithMiddleware = applyMiddleware(reduxThunk, logger)(createStore);
where logger just console.log the whole state before and after every dispatch. So I know that before the dispatch for the reducer function, the "tasks" is populated after a first call.
Here is how I'm combining reducers:
import { combineReducers } from 'redux';
import {reducer as form} from 'redux-form';
import {reducer as uiReducer} from 'redux-ui';
import authReducer from './auth_reducer';
import treeReducer from './tree_reducer';
import media_asset_list_reducers from './media_asset_list_reducers';
import tasks from './tasks';
const reducers = combineReducers({
form: form,
auth: authReducer,
tree: treeReducer,
media_asset_list: media_asset_list_reducers,
tasks: tasks,
ui: uiReducer
});
export default reducers;
Can anyone help me?
Thanks
You arenot showing how are you combining reducers. But it seems to me that half of your reducer is written to get substate in form tasks.list, but it returns new state in form just list.
If you compose reducers with combineReducers, each of the combined reducers gets just its subpart of state (and that is what it should return as well)
Try:
import {DROP_TASK} from '../actions/types'
export default function (state = {}, action) {
switch (action.type){
case(DROP_TASK):
return {...state, list: [...state.list, action.payload]};
default:
return state
}
}
Your reducer will receive the state.tasks slice of the state already, so there is no need to include .tasks in this reducer.
This will result in a state tree like:
{
... //other reducers
tasks: {
list: []
}
}
If you want to remove the list layer and just have tasks be a list you can change the reducer to:
import {DROP_TASK} from '../actions/types'
export default function (state = [], action) {
switch (action.type){
case(DROP_TASK):
return [...state, action.payload];
default:
return state
}
}
Also, DROP_TASK seems like an odd action type for adding an item to list... but not knowing more about your app, this may still be appropriate, so ignore this if so.

Resources