Check out this for a great introduction on how to use and setup redux modularly. You should not need another package to setup Redux modularly. See the Child's Play project for an example of modular redux without any extra packages. I'll leave the implementation to that link and talk more about the why. Regular Redux usually involves one large file containing the applications initial state, and another large file containing all the applications reducers (the way to update the redux state). This makes sense in terms of why redux is used: the state in redux shouldn't be local to any single component, so organizing redux's state, actions, and reducers by component may not make much sense. Even with one file for a whole application, bloat can be avoided in these files if developers use Redux only when necessary.
However, it may sometimes make sense to organize redux state, actions, and reducer by which bigger wrapper component they are related to. Often times, our applications may be structured in a way where we have couple different sets of components with not a lot of interaction between them. In this scenario, organizing our redux into different modules and combining them may be a more understandable implementation.
This is an example of how to use redux to go "full circle." This goes over the how of redux, i.e. how to use it and start writing some redux related code.
This wiki page is based on this PR that adds edit mode to NNB. It mainly deals with the boolean state of isEditing
. However, it should be fairly similar to anything else you might want to do with redux.
There are a lot of files to keep track of, but fear not, each one is fairly simple by itself.
// reducers/initialState.js
const initialState = {
edit: {
isEditing: false
}
}
export default initialState
// actions/actionTypes.js
export const EDIT_MODE_ENABLED = 'EDIT_MODE_ENABLED'
export const EDIT_MODE_DISABLED = 'EDIT_MODE_DISABLED'
The purpose of explicitly declaring constants is so that we can reference the action types via a variable as opposed to a string value. This helps us ensure that typos get caught by compiler or runtime errors instead of causing spooky, hard to find bugs.
Note
: anywhere <>
is used, you should replace it with the thing you're trying to add. In this example, it will be edit
.
// actions/<>.action.js
import * as actionTypes from './actionTypes'
function editModeEnabled() {
return { type: actionTypes.EDIT_MODE_ENABLED, payload: true }
}
function editModeDisabled() {
return { type: actionTypes.EDIT_MODE_DISABLED, payload: false }
}
Recall that an action is simply an object that contains a type
and a payload
. An action creator is a simply a function that creates an action. (how insightful varun...)
Note
: the action creator should be called the same thing as its corresponding action, but in camelCase.
// actions/<>.action.js
// action creators above
export function enableEditMode() {
return dispatch => dispatch(editModeEnabled())
}
export function disableEditMode() {
return dispatch => dispatch(editModeDisabled())
}
These should return functions that dispatch your actions. Dispatching actions is what "fires" them, which will then let redux know internally that a reducer should pick it up to process them.