By Yazeed Bzadough
In order to ensure the readability of the article, free translation is used instead of literal translation.
90% protocol, 10% library. Redux is one of the most important JavaScript libraries ever created. Inspired by previous arts such as Flux and Elm, Redux makes JavaScript functional programming possible by introducing a scalable architecture with three simple points. If you’re new to Redux, consider reading the official documentation first.
1. Redux is mostly protocol
Consider the following simple counter application using the Redux architecture. Check out the Github Repo if you want to skip ahead.
1.1 State is stored in a tree
The state of the application looks like this:
const initialState = { count: 0 };
Copy the code
1.2 Action Declares the status change
According to the Redux protocol, we do not modify the state directly.
// Do not do the following in Redux applications
state.count = 1;
Copy the code
Instead, we create all the behaviors that a user might use in the application.
const actions = {
increment: { type: 'INCREMENT' },
decrement: { type: 'DECREMENT'}};Copy the code
1.3 Reducer Explains the behavior and updates the status
The last architectural part is called Reduer, which, as a pure function, returns a new copy of the state based on the previous state and behavior.
- if
increment
If triggered, the value increasesstate.count
- if
decrement
Is triggered, then reducestate.count
const countReducer = (state = initialState, action) = > {
switch (action.type) {
case actions.increment.type:
return {
count: state.count + 1
};
case actions.decrement.type:
return {
count: state.count - 1
};
default:
returnstate; }};Copy the code
1.4 There is no Redux yet
Did you notice that? So far we haven’t even touched the Redux library, we’ve just created some objects and functions, that’s why I call it “mostly protocol”, 90% of Redux applications don’t really need Redux.
2. Start implementing Redux
To use this architecture, we have to put it into a store, and we will implement just one function: createStore. The usage is as follows:
import { createStore } from 'redux'
const store = createStore(countReducer);
store.subscribe((a)= > {
console.log(store.getState());
});
store.dispatch(actions.increment);
// logs { count: 1 }
store.dispatch(actions.increment);
// logs { count: 2 }
store.dispatch(actions.decrement);
// logs { count: 1 }
Copy the code
Here is our sample initialization code, and we need a list of listeners and reducer provided with the initialization status.
const createStore = (yourReducer) = > {
let listeners = [];
let currentState = yourReducer(undefined{}); }Copy the code
Whenever someone subscribes to our Store, they are added to the Listeners’ array. This is important because every time someone dispatches an action, all of the listeners need to be notified within the event cycle. Calling the yourReducer function with a undefined and an empty object will return an initialState, which is what we returned when we called store.getState(). With that said, let’s create this method.
2.1 store. GetState ()
This function is used to return the latest state from the store, which we need to update our view every time the user clicks a button.
const createStore = (yourReducer) = > {
let listeners = [];
let currentState = yourReducer(undefined{});return {
getState: (a)= > currentState
};
}
Copy the code
2.2 store. The dispatch ()
This function takes an action as its input and feeds this action and currentState back to yourReducer to get a new state, and the Dispatch method notifies every listener that subscribed to the current store.
const createStore = (yourReducer) = > {
let listeners = [];
let currentState = yourReducer(undefined{});return {
getState: (a)= > currentState,
dispatch: (action) = > {
currentState = yourReducer(currentState, action);
listeners.forEach((listener) = >{ listener(); }); }}; };Copy the code
2.3 store. The subscribe (the listener)
This method lets you be notified when the Store receives an action, calling store.getState() to get the latest status and update the UI.
const createStore = (yourReducer) = > {
let listeners = [];
let currentState = yourReducer(undefined{});return {
getState: (a)= > currentState,
dispatch: (action) = > {
currentState = yourReducer(currentState, action);
listeners.forEach((listener) = > {
listener();
});
},
subscribe: (newListener) = > {
listeners.push(newListener);
const unsubscribe = (a)= > {
listeners = listeners.filter((l) = >l ! == newListener); };returnunsubscribe; }}; };Copy the code
Also, the SUBSCRIBE function returns another function, unsubscribe, which allows you to unsubscribe when you are no longer interested in store updates.
Clean up your code
Now let’s add the button logic and look at the final source code:
// Simplified createStore function
const createStore = (yourReducer) = > {
let listeners = [];
let currentState = yourReducer(undefined{});return {
getState: (a)= > currentState,
dispatch: (action) = > {
currentState = yourReducer(currentState, action);
listeners.forEach((listener) = > {
listener();
});
},
subscribe: (newListener) = > {
listeners.push(newListener);
const unsubscribe = (a)= > {
listeners = listeners.filter((l) = >l ! == newListener); };returnunsubscribe; }}; };// Architectural components of Redux
const initialState = { count: 0 };
const actions = {
increment: { type: 'INCREMENT' },
decrement: { type: 'DECREMENT'}};const countReducer = (state = initialState, action) = > {
switch (action.type) {
case actions.increment.type:
return {
count: state.count + 1
};
case actions.decrement.type:
return {
count: state.count - 1
};
default:
returnstate; }};const store = createStore(countReducer);
/ / DOM elements
const incrementButton = document.querySelector('.increment');
const decrementButton = document.querySelector('.decrement');
// Add click events to the button
incrementButton.addEventListener('click', () => {
store.dispatch(actions.increment);
});
decrementButton.addEventListener('click', () => {
store.dispatch(actions.decrement);
});
// Initialize the UI view
const counterDisplay = document.querySelector('h1');
counterDisplay.innerHTML = parseInt(initialState.count);
// Follow the new UI when distributing actions
store.subscribe((a)= > {
const state = store.getState();
counterDisplay.innerHTML = parseInt(state.count);
});
Copy the code
Let’s look at the final view again:
Original: www.freecodecamp.org/news/redux-…
4. Communication
This article will briefly take a look at the three architectural components of Redux and how to implement a simplified version of Redux. We hope to have a further understanding of Redux and discuss the technology with you.
The article has been updated toMaking a blog, if your article is ok, welcome to STAR!
One of your likes is worth more effort!
Grow up in adversity, only continue to learn, to become a better yourself, with you!