Access redux state anywhere in your code through reducers, and optionally split your reducers into smaller 'reduce' functions that operate per action
npm install redux-named-reducers --save
Create a named reducer
import { createNamedReducer } from "redux-named-reducers";
//define all the state you will access in initial state
const initialState = {
state1: "default1",
state2: "default2"
};
function reducer(state = initialState, action) {
//reducer logic goes here
}
export const moduleA = createNamedReducer({
moduleName: "moduleA",
reducer: reducer
});
Add the enhancer
import { createStore, compose } from "redux";
import { namedReducerEnhancer } from "redux-named-reducers";
import { moduleA } from "./moduleA";
const store = createStore(moduleA, compose(namedReducerEnhancer(moduleA.reducer), ...otherEnhancersOrMiddleware));
Access the state from anywhere in your code
import { getState } from "redux-named-reducers";
import { moduleA } from "./moduleA";
function someFunction() {
const moduleName = moduleA.moduleName;
const state1 = getState(moduleA.state1);
const state2 = getState(moduleA.state2);
}
Use it to directly access state in mapDispatchToProps()
const mapDispatchToProps = dispatch => {
return {
onClick: () => {
dispatch(someAction(getState(moduleA.state1)));
}
};
};
Create a named reducer passing an initial state option
import { createNamedReducer } from "redux-named-reducers";
export const moduleA = createNamedReducer({
initialState: initialState
});
Create a reducer for each action or group of actions using 'reduce' function
//notice no need for '...state' just return the states which changed
moduleA.reduce(actions.ACTION1, action => {
state1: action.param1,
state2: action.param2
})
//if you are just changing state to a constant you can return an object directly
moduleA.reduce(actions.ACTION2, { state1: "nextState"} )
//multiple actions supported
moduleA.reduce([actions.ACTION3, actions.ACTION4], { state2: "nextState"} )
//...as well as 'redux-actions' like action creators that have a toString() method
moduleA.reduce(myActionCreator1, { state1: "nextState"} )
//'state' is not given because you can access it using the getState() method
moduleA.reduce(toggleState1, () => ({
state1: !getState(moduleA.state1)
})
Just pass the root reducer to the enhancer
import { combineReducers, createStore, compose } from "redux";
import { namedReducerEnhancer } from "redux-named-reducers";
import { moduleA } from "./moduleA";
import { moduleB } from "./moduleB";
const rootReducer = combineReducers({
[moduleA.moduleName]: moduleA.reducer,
[moduleB.moduleName]: moduleB.reducer
});
const store = createStore(rootReducer, compose(namedReducerEnhancer(rootReducer), ...otherEnhancersOrMiddleware));
Add an externalState option with a list of external state with default values
export const moduleA = createNamedReducer({
moduleName: "moduleA",
reducer: reducer,
externalState: { extState1: null, extState2: "" }
});
In the main app link the external state to other modules (Note: Since version v1.0.7 you must use linkState() to link states, old method is no longer supported)
import { linkState } from "redux-named-reducers";
linkState(moduleA.extState1, moduleB.state1);
linkState(moduleA.extState2, moduleC.state1);
You can then access the external state from the local module
const extState1 = getState(moduleA.extState1);
const extState2 = getState(moduleA.extState2);
Each named reducer state is just a selector so you can use it in reselect (since version 1.0.7 only)
import { createSelector } from 'reselect';
import { moduleA } from "./moduleA";
import { moduleB } from "./moduleB";
const mySelector = createSelector(
[ moduleA.state1, moduleA.extState1, moduleB.state2 ],
(state1, extState1, state2) => {
//selector logic goes here
}
You can then use the selector as normal, or if you link it to your state then you can access it anywhere in your code
linkState(moduleA.extState1, mySelector);
const derivedState = getState(moduleA.extState1);
getState() currently works for first level state properties only. To access nested state you must do:
getState(moduleA.state1).subState1;