Introduce
Redux is the management tool popular state and quite controversial in the ecosystem React, because many complained Redux dev lengthy and unwieldy. Personally, I do not find it difficult, but sometimes it is a bit lengthy. Because in order to create a complete store , we need to go through quite a few steps, create many files with a lot of repetitive code , in addition, redux doesn’t build a clear code for writing logic. , as well as in addition to redux , sometimes we need to install some more libraries like middleware, selectors … to be able to write complete state management logic .
redux-toolkit is a package created to solve most of the above problems, developed by the owner of the reduxjs team , helping us to write redux code quickly, complete according to a unified standard.
In this article I will introduce redux-toolkit , the article will be for those who have used or know about redux , but for those of you who have never used redux , I think you should approach redux basic. Before, capture how it works as well as key concepts such as actions, reducer, store …
Install and create a store
Install redux-toolkit
1 2 3 4 5 6 | # NPM npm install @reduxjs/toolkit # Yarn yarn add @reduxjs/toolkit |
Create a store in redux
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token comment">// store.js</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> createStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span> <span class="token keyword">const</span> <span class="token constant">INCREASEMENT</span> <span class="token operator">=</span> <span class="token string">'increasement'</span> <span class="token keyword">const</span> <span class="token constant">DECREASEMENT</span> <span class="token operator">=</span> <span class="token string">'decreasement'</span> <span class="token comment">// actions</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">increasement</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> type <span class="token operator">:</span> increasement <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">decreasement</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token operator">:</span> decreasement <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> initialState <span class="token operator">=</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">rootReducer</span> <span class="token punctuation">(</span> <span class="token parameter">state <span class="token operator">=</span> initialState <span class="token punctuation">,</span> action</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span> action <span class="token punctuation">.</span> type <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token constant">INCREASEMENT</span> <span class="token operator">:</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">break</span> <span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token constant">DECREASEMENT</span> <span class="token operator">:</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">break</span> <span class="token punctuation">;</span> <span class="token keyword">default</span> <span class="token operator">:</span> <span class="token keyword">return</span> state <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span> <span class="token punctuation">(</span> rootReducer <span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> store |
We have just instantiated the most basic store using redux , with only one state ( count ) and listened to only 2 action types to perform count increments or decrements. However, we still find it a bit complicated, right, even if it’s just a simple store , like the type declaration, it’s a bit verbose, and this value is only used when creating actions and in reducer .
1 2 3 | <span class="token keyword">const</span> <span class="token constant">INCREASEMENT</span> <span class="token operator">=</span> <span class="token string">'increasement'</span> <span class="token keyword">const</span> <span class="token constant">DECREASEMENT</span> <span class="token operator">=</span> <span class="token string">'decreasement'</span> |
In addition, we have to manually handle logic inside the reducer using js without any clear rules, for example the action does not have to return the type , the reducer does not actually need to use a switch to listen for action .
redux-toolkit: configureStore
We start with the configureStore function of the redux-toolkit . Like the above example, we initialize a store using redux ‘s createStore function with the input parameter as a reducer , configureStore will do the same thing, we will initialize the store according to the following method:
1 2 3 4 5 6 7 8 | <span class="token keyword">import</span> <span class="token punctuation">{</span> configureStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@reduxjs/toolkit'</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">configureStore</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> reducer <span class="token operator">:</span> rootReducer <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
The syntax doesn’t make much difference, right? However, instead of just creating a simple store , configureStore will default to allowing redux devtool to be used to debug and monitor state updates as well as pre-set some middleware .
redux-toolkit: createAction
Next, we will learn how to create an action with createAction , take the parameter as a string and return an action constructor with the type that will be the string value passed.
1 2 3 4 5 6 7 | <span class="token keyword">import</span> <span class="token punctuation">{</span> createAction <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@reduxjs/toolkit'</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> increment <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'INCREMENT'</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token function">incrementNew</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// {type: "INCREMENT"}</span> |
First, createAction helps us to initialize the action more concisely with creating the action with a simple javascript function . In addition, in the above example, I did not pre-declare the type value of the action, but passed the string directly to the parameter, because createAction provides the ability to access the type of the action , saving a few more lines of code, the syntax will be as follows
1 2 3 4 5 6 7 8 9 | <span class="token keyword">import</span> <span class="token punctuation">{</span> createAction <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@reduxjs/toolkit'</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> increment <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'INCREMENT'</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> increment <span class="token punctuation">.</span> <span class="token function">toString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// "INCREMENT"</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> increment <span class="token punctuation">.</span> type <span class="token punctuation">)</span> <span class="token comment">// "INCREMENT"</span> |
redux-toolkit: createReducer
Another function I want to introduce in this article, we simply will not have to create reducer completely with pure js anymore.
createReducer allows us to initialize reducer in a simpler and more intuitive way than in plain writing, logic looks more intuitive as a reference object , with each key is a type and value is a reducer function . No more wordy, let’s see the syntax:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">import</span> <span class="token punctuation">{</span> createReducer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@reduxjs/toolkit'</span> <span class="token keyword">const</span> increment <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'INCREMENT'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> decrement <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'DECREMENT'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> initialState <span class="token operator">=</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token function">createReducer</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span> increment <span class="token punctuation">.</span> type <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> decrement <span class="token punctuation">.</span> type <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
createReducer takes 2 parameters as the initial value of the state and an object to help the reducer listen and update the state , if in the previous example you wondered why the action created by createAction has 2 options to access the types , the purpose of your reducer will be a little shorter. Based on the computed property of es6 we can completely rewrite the following:
1 2 3 4 5 | <span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token function">createReducer</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span> increment <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> decrement <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Due descreasement increasement and not a string, computed property will automatically call the toString (), similar to [increasement.toString ()].
Refactor back to the entire original store
Let’s take a look at the original store that we created, which was completely ported to the redux-toolkit functions :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token comment">// store.js</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> configureStore <span class="token punctuation">,</span> createAction <span class="token punctuation">,</span> createReducer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@reduxjs/toolkit'</span> <span class="token punctuation">;</span> <span class="token comment">// actions</span> <span class="token keyword">const</span> increasement <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'increasement'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> decreasement <span class="token operator">=</span> <span class="token function">createAction</span> <span class="token punctuation">(</span> <span class="token string">'decreasement'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> initialState <span class="token operator">=</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> rootReducer <span class="token operator">=</span> <span class="token function">createReducer</span> <span class="token punctuation">(</span> initialState <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span> increasement <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> decreasement <span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token parameter">state</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token operator">:</span> state <span class="token punctuation">.</span> count <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">configureStore</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> reducer <span class="token operator">:</span> rootReducer <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> store |
redux-toolkit clearly helps redux become clear, much more concise, but it requires you to understand redux first, then applying redux-tookit will feel quite happy. In this article, I introduced some of the main api of redux-toolkit , and that is not all, redux-toolkit still has many good things for us to learn, I will introduce in the following sections.