How to Build Your Own Redux to Better Understand How it Works.
- Arthur Sukhinin

- Mar 15, 2022
- 3 min read
Redux https://redux.js.org/ is a popular container for work with state for JavaScript. Redux can be used with React, Angular, Vue, Mithril and more. Why we are use the Redax?
With Redux, the state of your application is kept in a store, and each component can access any state that it needs from this store. It is very important when your application starts to grow. Redux allows you to manage your app’s state in a single place. It helps you make a changes in your app easier. But sometimes it is quite difficult to figure out how exactly the Redux works. To better understand this, I tried to write simplified Redux code.
Here's a simple example of a counter application:
./index.js
const counter = document.getElementById('counter') const addBtn = document.getElementById('add') const remBtn = document.getElementById('rem')
let state = 0 function render() { counter.textContent = state.toString() } addBtn.addEventListener('click', () => { state++ render() }) subBtn.addEventListener('click', () => { state-- render() })
Now we have a state=0. And we can change it by 2 buttons(add and rem) and render it to a browser.
Next I would like to write here my own Redux code. You can see the Redux Data Flow below.

First I add a createStore.js file in my src folder. In my index.js file I'm going to change my state constant:
const store = createStore()
and add: import {createStore} from './createStore'
The createStore.js file I'm going to create similar like Redux createStore function. We need to create dispatch, subscribe and getState methods there. getState method for get a up-to-date state, dispatch method for make a changes in a state and subscrabe method for call all dependent objects.
export function createStore(rootReducer, initialState) {
let state = rootReducer(initialState, {type: '@@INIT'})
const subscribers = []
return {
dispatch(action) {
state = rootReducer(state, action) subscribers.forEach(sub => sub())
},
subscribe(callback) {
subscribers.push(callback)
},
getState() {
return state
},
}}}
How it work here? If you refer to the Redux diagram you can see that dispatch(action) coming from a component. In dispatch method we going to change our state by using rootReducer. What is Reducer? We get it like parameter createStore function. Actually Reducer is a function. We going to call it with our state and action like parameters to change the state. Action is small function which get us know what type of change we have to do. Next we just need to inform all our subscribers about changes in a state. Let go ahead to create action function and rootReducer.
I'm going to create a redux folder. In this folder I will make action.js and rootRedux.js files.
./redux/action.js
export function increment() { return { type: 'INCREMENT' } }
export function decrement() { return { type: 'DECREMENT' } }
./redux/rootReducer.js
function counterReducer(state = 0, action) {
switch(action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state }
Now our index.js can be changed:
./index.js
import { rootReducer } from '../redux/rootReducer'
import { decrement, increment } from '../redux/actions'
const counter = document.getElementById('counter') const addBtn = document.getElementById('add') const remBtn = document.getElementById('rem')
const store = createStore( rootReducer, 0) addBtn.addEventListener('click', () => { store.dispatch(increment()) }) subBtn.addEventListener('click', () => { store.dispatch(decrement()) })
store.subscribe( () => { const state = store.getState()
counter.textContent = state
}
store.dispatch({ type: 'INIT_APP'})
Looks much better and work! Now we don't have any logic in our index.js. We call store.dispatch({ type: 'INIT_APP}) for render initial state = 0 after page reload.
We did it! And for check that everything work perfect I'm going to install Redux and check my work. Lets run npm install redux and import createStore not from our createStore.js but from Redux library:
import {applyMiddleware} from 'redux'
Given that we changed all to the Redux library, everything remained working. It helped me a lot in the Redux understanding.



Comments