Redux: Implementing Store from Scratch

Dan Abramov
InstructorDan Abramov

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 9 months ago

Learn how to build a reasonable approximation of the Redux Store in 20 lines. No magic!

[00:00] In the previous video we looked at how to implement a simple counterexample using the Create/Store function provided by Redux and the store object it returns that provides the get straight method to get the current application state, the dispatch method, to change the current application state by dispatching an action, and the subscribe method to subscribe to the changes and re-render our application with the current state of the app.

[00:29] If you're like me you prefer to understand the tools that you're using. In this tutorial we're going to re-implement the Create/Store function provided by Redux from scratch. The first and the only form of what we know so far argument to the Create/Store function is the reducer function provided by the application.

[00:52] We know that the store holds the current state. We keep it in a variable, and the get straight function is going to return the current value of that variable. This function, combined with the Dispatch function and a Subscribe function on a single object is what we call the Redux store.

[01:14] Because the Subscribe function can be called many times, we need to keep track of all the changed listeners. Any time it is cold we want to push the newly listener into the array. Dispassion in action is the only way to change the internal state.

[01:30] In order to calculate the new state we call the reducer with the current state and the action being dispatched. After the state was updated, we need to notify every changed listener, by calling it.

[01:44] There is an important missing piece here. We haven't provided a way to unsubscribe a listener. Instead of adding a dedicated Unsubscribe method, we'll just return a function from the Subscribe method that removes this listener from the listeners' array.

[02:03] Finally, by the time the store is returned we wanted to have the initial state populated. We're going to dispatch a dummy action just to get the reducer to return the initial value.

[02:17] This implementation of the Redux store apart from a few minor details in that case is, is the Create/Store was shipped with Redux.

Lucas
Lucas
~ 5 years ago

Hello, i didn't understand why needed to return the function that remove de subscriber listener of listeners array.

Negin Basiri
Negin Basiri
~ 5 years ago

Hi,

I have a very basic and fundamental question.

Why do we need to implement createStore while Redux provide it to us?

In which circumstances we need to create our own store and in which situation we can use Redux store?

Sammy Gonzales-Luna
Sammy Gonzales-Luna
~ 5 years ago

I too was confused by this aspect of the createStore implementation. If you listen close, Dan mentions that the purpose of the return statement is to avoid having a separately defined method to UN-subscribe a listener. Therefore, the return statement returns an anonymous function that takes a listener and removes that listener from the listeners array.

Justin Hugg
Justin Hugg
~ 5 years ago

He is just showing how it works by providing a simplified example of what goes on "behind the scenes."

Vadim Shvetsov
Vadim Shvetsov
~ 5 years ago

And I want to extend your great answer with one thing, because it may be not obvious for everyone. We need to save store.subscribe(render) to a variable, which we will call with parenthesis for unsubscribe. It may seems like:

//For subscribe
let renderSubscription = store.subscribe(render);
//For unsubscribe
renderSubscription();
aaronisme
aaronisme
~ 5 years ago

I got a question about how to implement the unsubscribe here, why we are not providing an dedicated method to do it?

Lars
Lars
~ 4 years ago

If anyone is wondering how to unsubscribe a listener, you have to pass in the same listener you're about to remove (which is a little unintuitive), unless I'm missing something:

document.addEventListener('keyup', () => { 
   store.subscribe(render)(render);
}); 

You can modify createStore.subscribe to make things a little easier:

  const subscribe = (listener) => {
    if (listener) {
      listeners.push(listener);
    }
    
    return (toRemove) => {
      listeners = listeners.filter(l => l !== toRemove);
    };
  };


// Usage:
store.subscribe()(render);

Or, you know, just write a separate unsubscribe method.

Manuel Penaloza
Manuel Penaloza
~ 4 years ago

"Hello, i didn't understand why needed to return the function that remove de subscriber listener of listeners array."

I was also wondering about this, until I reached 05:00 of this video https://egghead.io/lessons/react-redux-extracting-container-components-filterlink ... there you can see this implementation and its purpose in action.

Monica
Monica
~ 2 years ago

Hello, i didn't understand why needed to return the function that remove de subscriber listener of listeners array.

That part took me a min too. He's just making a function available that we could use to remove a listener from the listeners array.

To use it, set your subscribe call equal to a variable. That stores the returned function.
const unsubscribeHey = store.subscribe(hey);

Then call that function later to unsubscribe the listener.
unsubscribeHey()

Check out https://codepen.io/mocasalter/pen/XvKKdZ?editors=0011