A Redux action is simply a JavaScript object that contains information about an action event that has occurred
dispatch()
Method
myReduxStore.dispatch(myActionCreator());
myReduxStore.dispatch( {type: myValue} );
(Alternate dispatch event)
The dispatch()
method is used to dispatch actions to the Redux store
In Redux, all state
updates are triggered by dispatching actions
Calling dispatch()
method and passing the value returned from an action creator sends an action back to the Redux store
Redux Reducer
const myReducer = (state=myDefaultState, action) => { return myNewState; };
A Redux reducer is a function that responsible for the state modifications that take place in response to actions
The reducer has no side effects, which it never calls an API endpoint and it never has any hidden surprises
The myReducer
takes state
and action
as arguments, and it always returns a new state
Another key principle in Redux is that state
is read-only
In other words, the reducer function must always return a new copy of state and never modify state directly
Redux does not enforce state immutability, however, user are responsible for enforcing it in the code of the reducer functions
Handling an action
const myDefaultState = {login: false};
const myReducer = (state=myDefaultState, action) => {
if (action.type === "LOGIN") { return {login: true}; }
else { return state; }
};
const myReduxStore = Redux.createStore(myReducer);
const myLoginAction = () => {
return {type: "LOGIN"};
};
A common practice when working with Redux is to assign action types as read-only constants, then reference these constants wherever they are used
User can refactor the code there're working with to write the action types as const
declarations
It's generally a convention to write constants in all uppercase, and this is standard practice in Redux as well
const MYLOGINACTION = "LOGIN";
const myDefaultState = {login: false};
const myReducer = (state=myDefaultState, action) => {
if (action.type === "LOGIN") { return {login: true}; }
else { return state; }
};
const myReduxStore = Redux.createStore(myReducer);
Handling multiple actions with switch
statement
There is a situation where user are managing user authentication in the Redux store
User want to have a state representation for when users are logged in and when they are logged out
User need action creators that create actions corresponding to user login and user logout, along with the action objects themselves
At this point, the state immutability is not to be worried about since it is small and simple in the following example
For each action, user can return a new object, like {authenticated: true}
Plus, the default
case in switch
statement must be included
This is important because once the app has multiple reducers, they are all run any time an action dispatch is made, even when the action isn't related to that reducer
In such a case, user want to make sure that the statement return the current state
const MYLOGIN = "LOGIN";
const MYLOGOUT = "LOGOUT";
const myDefaultState = {authenticated: false};
const myAuthentication = (state=myDefaultState, action) => {
switch (action.type) {
case MYLOGIN: return {authenticated: true};
case MYLOGOUT: return {authenticated: false};
default: return myDefaultState;
}
};
const myReduxStore = Redux.createStore(myAuthentication);
const myLoginAction = () => {
return {type: MYLOGIN}
};
const myLogoutAction = () => {
return {type: MYLOGOUT}
};
combineReducers()
Method
Redux.combineReducers();
The combineReducers()
method accepts an object as an argument in which user define properties which associate keys to specific reducer functions
The name user give to the keys will be used by Redux as the name for the associated piece of state
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";
const counterReducer = (state=0, action) => {
switch(action.type) {
case INCREMENT: return state + 1;
case DECREMENT: return state - 1;
default: return state;
}
};
const LOGIN = "LOGIN";
const LOGOUT = "LOGOUT";
const authReducer = (state = {authenticated: false}, action) => {
switch(action.type) {
case LOGIN: return {authenticated: true};
case LOGOUT: return {authenticated: false};
default: return state;
}
};
const rootReducer = Redux.combineReducers( {
count: counterReducer,
auth: authReducer
} );
const store = Redux.createStore(rootReducer);