DEV Community

Clint Maruti
Clint Maruti

Posted on

Redux - as simple as it can get

Redux, by it's definition, is a state management framework that can be used with different web technologies, including react and ruby. Redux is not part of react!

It is efficient when you are working on a large application that requires changing states in different components. Assuming you are working on an application that has over 10 components, and each component has its own local state, the entire state of the application can be managed on a single object housed in Redux store.

I am going to share some basic steps I use to set up redux.

Step 1: Creating your Initial State

A state in simple terms, is a JavaScript object that stores dynamic data that will be used in the components. This data determines the component's behaviour. Assuming Student represents your application's current state in time. Let's define our student current state:-

const initialState = {
  name: 'Valerie',
  grade: 4,
  age: 8
};
Enter fullscreen mode Exit fullscreen mode

Step 2: Defining your Action(s) and Action Creator(s)

An Action is simply a JavaScript object that contains information that send data from your application to your store. They are the only source of information for the store.
In our example, our actions can be to enroll a student, pay their fees or assign them a dormitory. Let's define an action. Defining a Redux action is as simple as declaring an object with a type property. We first declare our action type by assigning it to a constant variable. This is just best practice.

const ENROLL = 'ENROLL';
Enter fullscreen mode Exit fullscreen mode

Next, we define our action creator which will be used to send the action to the store. An action creator is simply a JavaScript function that returns an action.

const enrollStudentAction = (status) => {
  return {
    type: ENROLL,
    status: status
  }
};
Enter fullscreen mode Exit fullscreen mode

Step 3: Creating your reducer(s)

A Reducer describes how our state changes in relation to the actionsthat we have described. A reducer is a function that takes in the state as the first argument and action. Reducers in Redux are responsible for the state modifications. Reducers return a new state.

const studentReducer = (state = initialState, action) => {
  switch (action.type) {
    case ENROLL:
      let newInitialState = Object.assign({},state);
       newInitialState.status= action.message;
        return newInitialState;
    default:
      return state;
  }
}
Enter fullscreen mode Exit fullscreen mode

N/B
In Redux, state is read-only i.e, the reducer function must always return a new copy of state and never modify state directly. Redux does not enforce state immutability, however, you are responsible for enforcing it in the code of your reducer functions.

In our case, our state is an object. In order to enforce state immutability in objects, we use Object.assign() utility. Object.assign() takes a target object and source objects and maps properties from the source objects to the target object. Any matching properties are overwritten by properties in the source objects.

So our Object.assign({},state) utility takes in an empty object as the target object and our state which is our initialState object as the source. This just creates a clone of our state. Now that we have our state object clone, we can then add a new property in it. Our new property is status and is set to a value 'enrolled'.

Step 4: Creating our store

As I mentioned above, the store houses our state and all the logic to update it are passed to it. To create our store, we use a createStore() function from redux. It takes the reducer, state - or if you like to call it preloaded state and in some cases enhancers e.g. applymiddleware(). But I won't go in to that. I want to this as minimal as possible.

const store = Redux.createStore(studentReducer, initialState)
Enter fullscreen mode Exit fullscreen mode

There we have our store ready!

State 6: Subscribe

Subscribe just lets you know every time the store changes. If you're writing a react-redux application then you never need it because react-redux does this for you. (i.e. essentially it watches for changes and then tells react to redraw). For example in our case, if we want to know whether the our student state is changing, we can add an event listener. It will be called any time an action is dispatched, and some part of the state tree may potentially have changed. You may then call getState() to read the current state tree inside the callback. For example, in our case, if we want to check whether a new student is enrolled or not, we can create an event listener called handleChange like this:-

function handleChange() {
  const currentStudent = store.getState();
  if (currentStudent.status === 'enrolled') {
    console.log('A new Student is enrolled!');
  } else {
    console.log('Student not yet enrolled!');
  }
}
Enter fullscreen mode Exit fullscreen mode

then we subscribe this event to the store like this:-

store.subcribe(handleChange)
Enter fullscreen mode Exit fullscreen mode

Finally Dispatching our actions

Dispatching simply means, passing the logic (actions) that we have created to the redux store. This is the moment of truth now. We can now test our update logic.
Dispatch method is what you use to dispatch actions to the Redux store. Calling store.dispatch() and passing the value returned from an action creator sends an action back to the store.

store.dispatch(enrollStudentAction('Enrolled'));
Enter fullscreen mode Exit fullscreen mode

We can check that our state changes by calling getState() method on the store:-

// Log the initial state
console.log(store.getState()
Enter fullscreen mode Exit fullscreen mode

Once you do this, you will see that our state now has status: 'enrolled'` property at the bottom. We killed it!

Cheers!

Top comments (0)