Base Redux implementation
Redux is also powerful because of its simplicity, and you can even implement a simple Redux ecosystem with a few lines of code.
Redux stores all data in one place, the Store, so we implement:
- Events eventually modify state
- Listen for state changes so that we can change the UI
The first point above can be achieved in two small parts:
- Notify the Store when an action is generated
- Implement logic (code) to change state for store
As described above, using only HTML and javascript, without external libraries, we use the Flux concept to build a simple counter that can be added and subtracted using buttons.
index.html
<div>Count:<span id="counter"></span>
</div>
<button id="inc">increase</button>
<button id="dec">To reduce</button>
Copy the code
Use state to hold the count
counter.js
let state = {
counter: 3
}
Copy the code
Action is generated on each button click event and distributed using the Dispatch (action) function
document.getElementById('inc').onclick = (a)= > dispatch('INC')
document.getElementById('dec').onclick = (a)= > dispatch('DEC')
// In redux, the action must have a TPE attribute. Here we simply pass in a string that represents increment or decrement
function dispatch(action){
// To be determined, read on
}
Copy the code
Second, we need to define the code to update the HTML page
function updateView(){
document.getElementById('counter').innerText = state.counter
}
Copy the code
The UI displays the value in state, which is counter, so we need to notify updateView() every time the state changes to keep the HTML page up to date
subscribe(updateView)
// subscribe function is not yet defined and is used here. Please read on
Copy the code
At this point, we have created the basic structure of the counters. We use state to store counter values, the updateView function to update HTML, and define two functions, dispatch and SUBSCRIBE, to distribute actions and listen for state changes and notify the updateView function (call).
But we haven’t implemented the process of handling events yet. How does this simple Redux go through the steps of getting the action to change the HTML? To do this, we also need a Reducer function that accepts the current state and actions to return a new state and render the HTML with the new state.
Since our action has no type attribute and is just a string representing increase or decrease, our Reducer implementation is as follows
function reducer(state, action){
switch(action){
case 'INC':
return { ...state, counter: state.counter + 1 }
case 'DEC':
return { ...state, counter: state.counter - 1 }
default:
return state
}
}
Copy the code
Importantly, when the state changes, the Reducer must create a new state, make changes on the new state based on the action, and return the new state. (The new state can be understood as a different reference in JS, state is an object, and two objects with identical structure and key value are not equal, because they use time reference, i.e. memory address, when comparing ===)
It is an error to change state in the following way. Since the memory address of state has not changed, store cannot detect the change of state. We will explain why later
state.counter = state.counter + 1
Copy the code
The Dispatch function calls the Reducer function to get the new state and notify updateView to change the HTML
function dispatch(action){
const newState = reducer(state, action)
if(newState ! == state){ state = newState listeners.forEach(listener= > listener())
}
}
Copy the code
In the if determination, we know that state has changed by comparing memory locations. The listeners are an array of functions that need to be triggered if state has changed, such as updateView
const listeners = []
function subscribe(callback){
listeners.push(callback)
}
Copy the code
We’ve been listening to the updateView function with subscribe. At this point, our simple Redux counter is complete. We can click buttons to increase and decrease the count.
document.getElementById('counter').innerText = document.getElementById('counter').innerText + 1
Copy the code
This might be easy to do with the code above, but as our application grows and changes become more involved, the benefits of the Flux design pattern will become more apparent.
See the full counter application on Codepen
Redux – pure js and html implement redux
@Number_DDD
CodePen