in

Intro to Redux

Intro

Redux is a Javascript library that helps us manage state in more complicated applications. It is not designed to work exclusively with React, although it does integrate very well. I can be used on it’s own with other JavaScript applications.

For the following samples to work you will of course have to install redux, so take care of that if you are following along.

Redux Cycle

Action

An object that contains information about how we want to change some data within our central state.

An action will contain a type and a payload.

Action Creator

A function that creates an action object. Each action will contain unique information, but the format of each action should be the same. So when we create the Action Creator we will be writing out a schema of the action.

Let us take an example where we are creating actions that update the state of several insurance policies and their claims.

const createPolicy = (name, amount) => {
    return {
        type: 'CREATE_POLICY',
        payload: {
            name: name,
            amount: amount
        }
    };
};

const deletePolicy = (name) => {
    return {
        type: 'DELETE_POLICY',
        payload: {
            name: name,
        }
    };
};

const createClaim = (name, amountOfMoneyToCollect) => {
    return {
        type: 'CREATE_CLAIM',
        payload: {
            name: name,
            amountOfMoneyToCollect: amountOfMoneyToCollect
        }
    };
};

Note that we are just using an insurance company tracking their policies and claims as an example here to understand the Redux process.

Dispatch

The dispatch decides which reducer the action needs to be sent to. The action TYPE is what informs the dispatcher of which reducer it should route the action to.

Reducers

The reducers are going to do different things with the action depending on what our intentions are.

If Correct Action Type, Return New Array

Each reducer is a function that takes two arguments, always in the same order. The first is the current list of actions that have already been saved with that type, and the second is the new action. The output of this reducer is a new array that includes the new action.

// reducers
const claimsHistory = (oldListOfClaims, action) => {
    if (action.type === 'CREATE_CLAIM') {
        // we care about this action
        return [...oldListOfClaims, action.payload];
    }

};

If you are not familiar with the ... syntax, check out the refresher below. The key takeaway though is that we are creating a NEW array. We 100% of the time want our reducer to be returning a new array and not modifying the old one.

So we have checked to see if the action is the correct type of action to be sending to this reducer, if it is then we the action to the repository of this type.

Return Original Array If Incorrect Action Type

Lastly if we have passed in the wrong type of action we want to simply return the list of claims as it was.

// reducers
const claimsHistory = (oldListOfClaims, action) => {
    if (action.type === 'CREATE_CLAIM') {
        // we care about this action
        return [...oldListOfClaims, action.payload];
    }

    // we don't care about this action.
    return oldListOfClaims;
};

Default Value For First Action

We need to set a default value for the old array in case this is the first action of its type, in which case requesting that array would return undefined.

// reducers
const claimsHistory = (oldListOfClaims = [], action) => {
    if (action.type === 'CREATE_CLAIM') {
        // we care about this action
        return [...oldListOfClaims, action.payload];
    }

    // we don't care about this action.
    return oldListOfClaims;
};

ES2015 Array Shorthand …

The ... notation creates a new array starting with the named array, and then adds the additional items to the array.

Babel: Learn ES2015, Default + Rest + Spread

Full Reducers Example

Continuing with our example of creating reducers for an mock insurance company. Above we made the reducer that handles adding a claim to the claim list. Now let’s add several more examples.

Below we will also handle what is happening in our accounting department, whether we are gaining money for a new policy or paying out money for a claim. And also the ability to add or remove policies.

Note that in all these examples we are returning a new array. In reducers we never modify the existing array. We always return a new array.

// REDUCERS

// create an insurance claim
const claimsHistory = (oldListOfClaims = [], action) => {
    if (action.type === 'CREATE_CLAIM') {
        // we care about this action
        return [...oldListOfClaims, action.payload];
    }

    // we don't care about this action.
    return oldListOfClaims;
};

// does the action affect our money balance? Default balance of $100
const accounting = (currentBalance = 100, action) => {
    if (action === 'CREATE_CLAIM') {
        return currentBalance - action.payload.amountOfMoneyToCollect;
    } else if (action.type === 'CREATE_POLICY') {
        return currentBalance + action.payload.amountOfMoneyToCollect;
    }

    return bagOfMoney;
};

// if new policy add to policy list
// if removing, create new list without payload.name
const policies = (listOfPolicies = [], action) => {
    if (action.type === 'CREATE_POLICY') {
        return [...listOfPolicies, action.payload.name];
    } else if (action.type === 'DELETE_POLICY'){
        return listOfPolicies.filter(name => name !== action.payload.name);
    }

    return listOfPolicies;
};

State

An object that serves as the central repository of all data from the reducers.

Redux Store

Now that we have created all of our action schemas and our reducer functions, we tie all of these things together using a few Redux methods, to create the one all powerful object called store, where the current value of all of our states are stored inside of their objects (action schemas).

// wiring reducers together with store

// pull methods out of Redux library
const { createStore, combineReducers} = Redux;

// combining reducers
const ourDepartments = combineReducers({
    accounting: accounting,
    claimsHistory: claimsHistory,
    policies: policies
});

// create store, pass in ourDepartments
const store = createStore(ourDepartments);

// store object now represents our entire Redux application

// now if we create an action
const action = createPolicy('Alex', 20);

// use Redux dispatch method to run action through reducers
store.dispatch(action);

console.log(store.getState());
React Logo

React: Responsive Image Grid

react-redux_logo

Intro to React-Redux