Using Immutable JS and Redux - action is undefined - javascript

I am using Redux and Immutable JS.
I set up the store like this
import { combineReducers } from 'redux-immutable';
...
const rootReducer = combineReducers({});
import { initialState } from '../reducers/...';
export const store = createStore(
combineReducers(rootReducer, initialState),
composeEnhancers(
applyMiddleware(...middleware)
)
);
Now I get the following error
// reducers/.../initialState.js
export function foo(state = initialState, action) {
switch (action.type) {
...
...
TypeError: Cannot read property 'type' of undefined
and it highlights switch (action.type) {.
When I am not using redux-immutable and set up my store like this
import { ..., combineReducers } from 'redux';
export const store = createStore(
combineReducers({ initialState }),
composeEnhancers(
applyMiddleware(...middleware)
)
);
I do not get an error. I do not understand why it says that action.type is undefined. Any ideas?

combineReducers only takes reducers:
const yourRootReducer = combineReducers({ someReducer, someOtherReducer })
It doesn't take initialState, your individual stores can (and createStore though you usually don't need to there).
Your call to createStore should be:
const store = createStore(
rootReducer,
initialState, // can be undefined
composeEnhancers(
applyMiddleware(...middleware)
)
);
Assuming middleware is an array.

I think your code should look like this
export const store = createStore(
rootReducer, initialState,
composeEnhancers(
applyMiddleware(...middleware)
)
);
// I removed the combineReducers()
Reference: https://github.com/gajus/redux-immutable#usage
Example:
import {
combineReducers
} from 'redux-immutable';
import {
createStore
} from 'redux';
const initialState = Immutable.Map();
const rootReducer = combineReducers({}); // we use the combineReducers() here
const store = createStore(rootReducer, initialState); // and don't need to use it here

Your initialState should not be a Reducer.
You should only combine all your Reducers.
Your initial State should be an object (State).
e.g.
{
loaded: true,
someDataString: ''
}

Related

TypeError: Object(...) is not a function - I am lost

INDEX.JS FILE
import { compose, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import firebase from '../Firebase/Firebase';
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase';
import { reduxFirestore, getFirestore } from 'redux-firestore';
import rootReducer from './reducers';
// react-redux-firebase config
const rrfConfig = {
userProfile: 'users',
useFirestoreForProfile: true, // Firestore for Profile instead of Realtime DB
};
const composeEnhancers =
process.env.NODE_ENV === 'development'
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
: compose;
const store = createStore(
rootReducer,
composeEnhancers(
reactReduxFirebase(firebase, rrfConfig),
reduxFirestore(firebase),
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore }))
)
);
export default store;
I believe my formatting is correct, however, I am lost. Can someone help, please? Below are my two files in my reducers folder.Please feel free to ask any questions you may have, and I will do my best to answer them. I am seriously stuck.
REDUCERS -> AUTHREDUCER.JS
const initialState = {
}
export default(state = initialState, action) => {
return'dhdhdhd';
};
REDUCERS -> INDEX.JS
import {combineReducers} from 'redux';
import { firebaseReducer } from 'react-redux-firebase';
import authReducer from './authReducer';
export default combineReducers({
auth: authReducer,
firebase: firebaseReducer,
});`enter code here`
When running NPM start, I return this error :
"TypeError: Object(...) is not a function" at const store = createStore( .
checkout https://redux.js.org/api/createstore, I believe 2nd argument should be initial state
const initialState = {} // the initial value for your state
const store = createStore(
rootReducer,
initialState, // 2nd argument of createStore is initial state
composeEnhancers(
...
)
);
UPDATED:
checkout http://docs.react-redux-firebase.com/history/v3.0.0/docs/v3-migration-guide.html#remove-store-enhancer as they have deprecated the enhancer for react-redux-firebase
so
Remove the reactReduxFirebase from the enhancers
Use the ReactReduxFirebaseProvider
const rrfProps = {
...
};
const App = () => (
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfConfig}>
...
</ReactReduxFirebaseProvider>
</Provider>
);

Why React Redux dispatch twice when fire

The State
The tracing results
Each time when I click the button, the dispatch run twice, like the picture above.
This is the AppBar component and mapDispatchToProps function.
const mapStateToProps = state => {
return {
title: state.title
};
};
const mapDispatchToProps = {
onClick: () => {
return {
type: "TOGGLE_SIDEBAR"
};
}
};
const AppBar = props => (
<Box>
<Button icon={<Notification />} onClick={props.onClick} />
</Box>
);
const AppBatContainer = connect(
mapStateToProps,
mapDispatchToProps
)(AppBar);
export default AppBatContainer;
This is the reducer
import {
TOGGLE_SIDEBAR
} from "../constants/action-types";
const initialState = {
showBar: false
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_SIDEBAR:
return Object.assign({}, state, {
showBar: !state.showBar
});
default:
return state;
}
};
export default rootReducer;
This is the store.js
import { createStore, applyMiddleware, compose } from "redux";
import reduxThunk from "redux-thunk";
import rootReducer from "./reducers/index";
const composeEnhancers =
typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
trace: true,
traceLimit: 20
})
: compose;
const enhancer = composeEnhancers(applyMiddleware(reduxThunk));
const store = createStore(rootReducer, enhancer);
export default store;
All libraries are well imported. I tried remove redux-thunk, it is still the same result.
Thanks in advance.
Ref
React-Redux Counter example action firing twice I have viewed this questions on stackoverflow, and tried the answers, but no of them solved it.

Unable to store and retrieve the state from redux store

import * as actions from '../actions/login.Action';
let initialState = {
user: {
loggedIn: false,
userRole: "",
userEmail: "",
}
};
export default function (state = initialState, action) {
switch (action.type) {
case actions.LOGIN_SUCCESS:
return {
...state,
user: {
...state.user,
loggedIn: true,
userRole: action.userRole,
}
};
case actions.LOGOUT:
return initialState;
default:
return state;
}
}
this is my reducer triggered after the action login success and below is my store code
import { createStore, applyMiddleware, compose } from 'redux';
//import createSagaMiddleware from 'redux-saga';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory';
import rootReducer from './reducers';
const enhancers = [];
const middleware = [
thunk,
routerMiddleware(history)
];
export const history = createHistory();
const composedEnhancers = compose(
applyMiddleware(...middleware),
...enhancers
);
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);
const persistedState = localStorage.getItem('state') ? JSON.parse(localStorage.getItem('state')) : {};
store.subscribe(() => {
localStorage.setItem('reduxState', JSON.stringify(store.getState()));
});
in this case I am able to get the value from reducer but the issue is state value gets empty on page refresh whats wrong in this code i'm unable to identify clueless why the store doesn't save the state
I think you first call persistedState then define it Look below :
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);
const persistedState = localStorage.getItem('state') ?
JSON.parse(localStorage.getItem('state')) : {};
How about to change the position of persistedState so after that you have :
const persistedState = localStorage.getItem('state') ?
JSON.parse(localStorage.getItem('state')) : {};
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);

Redux Reducer is returning an [Object Object] , However i want string?

I am trying to change state of a const in redux.
i am trying my dispatch directly in the component i want to change the state in. The State is changed after dispatch,However i get back an Object. And when i Console.log , i get [Object][Object] , which before calling dispatch i used to get the Value of the state.
This is my Store.
import { createStore,applyMiddleware , compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
//const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
This is my Main Reducer.
import { combineReducers } from 'redux';
import sidebarReducer from './sidebarReducer';
export default combineReducers({
name : sidebarReducer
});
This is my CustomReducer , which i call sidebarReducer.
import { TOGGLE_SIDEBAR } from '../actions/types';
let sidebarname = "wrapper slide-menu";
export default function(state=sidebarname,action){
switch(action.type){
case TOGGLE_SIDEBAR:
console.log('reducer called');
console.log(state);
return{
...state,
sidebarname : action.payload
};
}
return state;
}
This is my Dispatch and MapStatetoProps Function.
const mapStatetoProps = state => ({
name : state.name
});
const mapDispatchtoProps = dispatch => ({
setName : (name) => {
dispatch({
type: "TOGGLE_SIDEBAR",
payload: name
})
}
})
export default connect(mapStatetoProps,mapDispatchtoProps)(App);
I successfully retrieved the State from the store , however when i dispatch i get back an Object.
sidebarReducer.js:13 reducer called
sidebarReducer.js:14 wrapper slide-menu
App.js:38 sidebarname is [object Object]
App.js:40 wrapper slide-menu
In handling your action, you are returning an object (check the curly braces):
return {
...state,
sidebarname: action.payload
};
Since your entire state is only the string sidebarname, you should return only the payload:
return action.payload
Alternatively, you can have your state be an object, and then your action return should work just fine:
let initialState = { sidebarmenu: "wrapper slide-menu" };
...
export default function(state=initialState,action){
...
}
your sidebarReducer just manages a string. just return action.payload on TOGGLE_SIDEBAR, not an object with a sidebarname property.

React+Redux - Uncaught Error: Expected the reducer to be a function

I tried simple react,redux,ajax working example and followed Reddit API tutorial, but I cannot create store and get error:
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;
Type of rootReducer is object, but why? Should I change createStore function to 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",
const rootReducer = combineReducers({
products,
specialPosts
});
const store = createStore( rootReducer, applyMiddleware( thunkMiddleware ));
The initial state is then created automatically from the initial states returned by the individual reducer functions. These individual states can be accessed as state.products and state.specialPosts
The problem was due to rootReducer being imported by "require" (ES5):
var rootReducer = require('./reducers.js');
If you import it via the ES6 method, it will correctly save the rootReducer.js' default automatically into rootReducer as you expected:
import rootReducer from './reducers';
I see you are mixing ES5 (require) and ES6 (import) in that file...I was mixing in my project as well, which is why I ran into this problem. More information can be found here: https://medium.com/#kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.2x2p2dx3m
When you create store first argument must be function that means reduce(()=>[]) parameter
Error:
import {createStore,applyMiddleware} from 'redux';
export default function configureStore(initialState) {
return createStore(
[],
{},
applyMiddleware()
);
}
Solution:
import {createStore,applyMiddleware} from 'redux';
export default function configureStore(initialState) {
return createStore(
()=>[],
{},
applyMiddleware()
);
}
When you see the error:
Uncaught Error: Expected the reducer to be a function
It does not necessarily mean that the reducer is not a function. If you experience this error, you should try creating the store with just the reducer. So like this:
createStore(reducer)
Which might be working.
In my case, the second parameter was wrong, because I didn't call compose and applyMiddleware in the correct order. So this is a correct setup that seems to have worked in my case:
export const createDebugStore = () => {
const options: EnhancerOptions = {}
const composeFunc = (typeof window !== 'undefined' && composeWithDevTools(options)) || compose;
const enhancer = composeFunc(applyMiddleware());
return createStore((state: any) => state || {}, enhancer);
}
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;
I use VS Code Insiders and sometimes changes are not saved correctly. So if you followed all of the above and the error is still there go to each file and press STRG+S. It solved the issue for me.
i have faced the same problem and it is solved by
const redux = require('redux');
const store = redux.createStore(reducer);
and my reducer is
const reducer = (state = initailState, action)=>{
if(action.type === 'BUY_CAKE'){
return {...state, numOfCake : state.numOfCake + 1}
}
if(action.type === BUY_ICECREAM){
return {...state, numOfIceCream : state.numOfIceCream + 1}
}
}

Categories

Resources