Hackernoon logoHow To Implement Simple State Container From Scratch by@kliukovkin

How To Implement Simple State Container From Scratch

Redux is about functional programming, so we will use pure functions and immutability. We separate representation and data layer, move the state from component to separate place. Clicking any button will trigger action. So we have an action and now we need to change the state of our application. We now have on direction, data down and actions up. We need to use the observer pattern to notify multiple objects about any events that happen to the object they’re observing. It's better to know what does observer pattern does.
image
Georgii Kliukovkin Hacker Noon profile picture

@kliukovkinGeorgii Kliukovkin

Developer.

Let's imagine that we have a component, a simple counter. The counter has a state and two buttons to manipulate with this state. We also have a function to render the state.

And here we have two problems:

  • representation layer and data layer are mixed. So, if you want to change one of them, you will touch both. It is a violation of SRP.
  • it is hard to support and maintain logic between components that have local states. Scalability problem arises.

To solve these problems we will use the FLUX approach which essentially means "Data downAction up". Clicking any button will trigger action. So we have an action and now we need to change the state of our application. But how we suppose to do that? 

image

Redux is about functional programming, so we will use pure functions and immutability. Functions, that will change our state we will call reducer. It will get the current state and action as an argument and will return to the new state. The function will look like this:

function reducer(state, action) {
    switch (action.type) {
	case 'INCREMENT':
            return state + 1;
	case 'DECREMENT':
	    return state - 1;
        default:
            return state;
    }
}

Now we need to create our store. Let's right the new function and call it

createStore
.

function createStore(reducer) {
    let state = 0;
    return {
        getState(){
            return state;
        },
        dispatch(action){
            state = reducer(state, action);
        }
    }
}

Before we can move on, it's better to know what does observer pattern does. Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing. Let's add this logic to our function:

function createStore(reducer) {
  let state = 0;
  const observers = [];
  return {
      getState(){
          return state;
      },
      subscribe(observer){
          observers.push(observer);
      },
      dispatch(action){
          state = reducer(state, action);
          observers.forEach(cb => cb());
      }
  }
}

And that's it! We separate representation and data layer, move the state from component to separate place, dependencies now have on direction, data down and actions up.

Tags

Join Hacker Noon

Create your free account to unlock your custom reading experience.