In this article I will share how to use the React-Redux Hooks . Firstly, let’s clarify a little Flow of React-Redux project that we are still familiar with.
redux, action, reducer, store, …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <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> initialState <span class="token operator">=</span> <span class="token punctuation">{</span> count <span class="token punctuation">:</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token constant">INCREASE</span> <span class="token operator">=</span> <span class="token string">'INCREASE'</span> <span class="token keyword">const</span> <span class="token constant">DECREASE</span> <span class="token operator">=</span> <span class="token string">'DECREASE'</span> <span class="token keyword">const</span> increaseAction <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token constant">INCREASE</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> increaseAction <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token constant">DECREASE</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">function</span> <span class="token function">reducer</span> <span class="token punctuation">(</span> state <span class="token operator">=</span> initialState <span class="token punctuation">,</span> action <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">INCREASE</span> <span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token operator">...</span> state <span class="token punctuation">,</span> count <span class="token punctuation">:</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 keyword">case</span> <span class="token constant">DECREASE</span> <span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token operator">...</span> state <span class="token punctuation">,</span> count <span class="token punctuation">:</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 keyword">default</span> <span class="token punctuation">:</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> reducer <span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> store |
We have a state with count = 0, count increases by 1 every time the store perform an action dispatch can type = INCREASE and decreases once the action to dispatch with type = DECREASE. Let’s say you understand the basic process of redux with action , reducer , because this article is for those who already know how to use redux .
Provider, connect
redux provides a state management tool for javascript applications, so it’s not just for react , to connect react with redux , we need to use the react-redux library, first we need to “transmit” the store we have just created into the main component of the application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">'react-dom'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Provider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-redux'</span> <span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">'./store'</span> <span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'containers/App'</span> <span class="token keyword">const</span> appRoote <span class="token operator">=</span> document <span class="token punctuation">.</span> <span class="token function">getElementById</span> <span class="token punctuation">(</span> <span class="token string">'root'</span> <span class="token punctuation">)</span> ReactDOM <span class="token punctuation">.</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token operator"><</span> Provider store <span class="token operator">=</span> <span class="token punctuation">{</span> store <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span> App <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Provider <span class="token operator">></span> <span class="token punctuation">,</span> appRoot <span class="token punctuation">)</span> |
Provider is an react-redux API , using React ‘s Context API makes it possible for all components in the application’s Component Tree to access the store we created, so it will be rendered above a “level”. for App – the main component of the application.
And if Provider acts as Context.Provider then connect is Context.Consumer, api we will use to “receive” state from the store and then transmit the action to be declared in each component needed as props.
We have the following App component :
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 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> connect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-redux'</span> <span class="token keyword">function</span> <span class="token function">App</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token operator"><</span> p <span class="token operator">></span> count <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> count <span class="token punctuation">}</span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> button onClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> props <span class="token punctuation">.</span> <span class="token function">increase</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">></span> increase <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> button onClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> props <span class="token punctuation">.</span> <span class="token function">decrease</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">></span> decrease <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token function-variable function">mapStateToProps</span> <span class="token operator">=</span> <span class="token punctuation">(</span> state <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> count <span class="token punctuation">:</span> state <span class="token punctuation">.</span> count <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token function-variable function">matchDispatchToProps</span> <span class="token operator">=</span> dispatch <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> increase <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">dispatch</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token string">'INCREASE'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> decrease <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">dispatch</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token string">'DECREASE'</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> withConnect <span class="token function">connect</span> <span class="token punctuation">(</span> mapStateToProps <span class="token punctuation">,</span> matchDispatchToProps <span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">withConnect</span> <span class="token punctuation">(</span> App <span class="token punctuation">)</span> |
OK, using redux is very basic and normal, but I have to admit that I don’t like to connect very much, firstly because the syntax is relatively confusing, especially for newbies, I’ve also fainted up and down to understand and Familiar with mapStateToProps or matchDispatchToProps , the second because connect uses the higher order component (hocs) so it creates multiple layers for the application’s component tree .
hooks api
react hooks allow us to develop react applications more simply, without using component classes with complex lifecycle systems, custom hooks allow us to create reusable states without using Hocs . Simple to understand, using hooks , the code is cleaner, much easier to understand.
react-redux recent version also provides API hooks that make it much easier for us to connect , and there is no need to use connect anymore, first I will refactor the App with hooks .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> useSelector <span class="token punctuation">,</span> useDispatch <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-redux'</span> <span class="token keyword">function</span> <span class="token function">App</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">useSelector</span> <span class="token punctuation">(</span> state <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token punctuation">)</span> <span class="token keyword">const</span> dispatch <span class="token operator">=</span> <span class="token function">useDispatch</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token operator"><</span> p <span class="token operator">></span> count <span class="token operator">=</span> <span class="token punctuation">{</span> count <span class="token punctuation">}</span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> button onClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">dispatch</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token string">'INCREASE'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">></span> increase <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> button onClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">dispatch</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> <span class="token string">'DECREASE'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">></span> decrease <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> App |
hmm, I was wondering, how can I use this briefly after using it, thinking about the old days when I was able to connect and felt so extreme. If you need to get to the state , use the useSelector , if you need to dispatch the action , useDispatch , don’t worry about the length of propsType when there are many states or actions that need to connect .
useSelector can also be used with the reselect library, the common redux state selector
1 2 3 4 5 6 7 8 9 | <span class="token keyword">import</span> <span class="token punctuation">{</span> createSelector <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'reselect'</span> <span class="token keyword">const</span> countSelector <span class="token operator">=</span> <span class="token function">createSelector</span> <span class="token punctuation">(</span> state <span class="token operator">=></span> state <span class="token punctuation">.</span> count <span class="token punctuation">,</span> count <span class="token operator">=></span> count <span class="token punctuation">)</span> <span class="token operator">...</span> <span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">useSelector</span> <span class="token punctuation">(</span> countSelector <span class="token punctuation">)</span> <span class="token operator">...</span> |
I tried writing useDispatch to use instead of react-redux ‘s existing useDispatch and didn’t see any errors at all:
1 2 3 4 5 6 7 8 | <span class="token keyword">import</span> <span class="token punctuation">{</span> useContext <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> ReactReduxContext <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-redux'</span> <span class="token keyword">function</span> <span class="token function">useDispatch</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">useContext</span> <span class="token punctuation">(</span> ReactReduxContext <span class="token punctuation">)</span> <span class="token keyword">return</span> store <span class="token punctuation">.</span> dispatch <span class="token punctuation">}</span> |
Easy to understand, right, then use it without thinking, note that in order to use the whole combo of hooks as above, your application needs to install react, react-dom v16.8 and above and react-redux. v7.1.0 and above . Also refer to react-redux hooks as well as dig deeper, you can read here . Above is my share on how to use some new hooks of react-redux , thanks for watching.
Demo code link: https://codesandbox.io/s/redux-hooks-rqs76