mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-19 08:19:48 +08:00
1294 lines
313 KiB
JavaScript
1294 lines
313 KiB
JavaScript
import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l="/assets/redux-usage.7df84df8.svg",o="/assets/redux-async-action.0dc40e11.svg",e="/assets/immutable.dc41f87b.gif",h=JSON.parse('{"title":"Redux","description":"","frontmatter":{},"headers":[],"relativePath":"note/Redux.md","filePath":"note/Redux.md","lastUpdated":1704513401000}'),t={name:"note/Redux.md"},c=p(`<h1 id="redux" tabindex="-1">Redux <a class="header-anchor" href="#redux" aria-label="Permalink to "Redux""></a></h1><h2 id="理解javascript的纯函数" tabindex="-1">理解JavaScript的纯函数 <a class="header-anchor" href="#理解javascript的纯函数" aria-label="Permalink to "理解JavaScript的纯函数""></a></h2><ul><li>函数式编程中有一个非常重要的概念 <strong>纯函数</strong>,JavaScript符合函数式编程的范式,所以也有纯函数的概念 <ul><li>在React开发中,纯函数被多次提及:</li><li>React组件被要求像一个纯函数(为什么是像,因为还有类组件)</li><li>Redux中有一个reducer的概念,同样是要求必须是一个纯函数</li></ul></li><li>掌握纯函数对于理解很多框架的设计都是有帮助的</li></ul><p>一个纯函数必然具备以下特征:</p><ul><li>确定的输入一定产生确定的输出</li><li>函数的执行过程中,不能产生副作用</li></ul><h2 id="为什么需要redux" tabindex="-1">为什么需要Redux <a class="header-anchor" href="#为什么需要redux" aria-label="Permalink to "为什么需要Redux""></a></h2><ul><li>JS需要管理的状态越来越多,越来越复杂</li><li>状态不断发生变化之间又相互依赖,这要求视图层也能同步更新</li><li>React提供了自动更新视图的方法,但状态仍需要手动管理</li><li>Redux可以帮我们管理状态,提供了<strong>可预测的状态管理</strong></li><li>框架无关,体积只有2KB大小</li></ul><h2 id="redux的核心理念" tabindex="-1">Redux的核心理念 <a class="header-anchor" href="#redux的核心理念" aria-label="Permalink to "Redux的核心理念""></a></h2><p>Redux的核心理念 Store</p><ul><li>定义一个统一的规范来操作数据,这样就可以做到对数据的跟踪</li><li><code>list.push()</code> <code>list[0].age = 18</code></li></ul><p>Redux的核心理念 Action</p><ul><li>Redux要求:要修改数据,必须通过Action来修改</li><li>所有数据的变化,必须通过派发(Patch)Action来更新</li><li>Action是一个普通的JS对象,用来描述此次更新的type与content</li><li><code>const action = { type: 'ADD_ITEM', item: { name: 'Ziu', age: 18 } }</code></li></ul><p>Redux的核心理念 Reducer</p><ul><li>如何将Store和Action联系在一起?</li><li>reducer是一个纯函数</li><li>完成的工作就是:将传入的state和action结合起来,生成一个新的state</li><li><code>patch</code> => <code>reducer</code> => <code>newState</code> => <code>Store</code></li></ul><h2 id="redux-demo" tabindex="-1">Redux Demo <a class="header-anchor" href="#redux-demo" aria-label="Permalink to "Redux Demo""></a></h2><p>下例中,通过<code>createStore</code>创建了一个Store(已经不推荐了)</p><ul><li>initialState用于在调用<code>createStore</code>时作为默认值传入<code>reducer</code></li><li>后续每次<code>store.dispatch</code>都会调用<code>reducer</code></li><li>通过<code>reducer</code>更新state中的数据</li></ul><p>在React中,可以通过<code>store.subscribe</code>注册State变化的监听回调</p><ul><li>当state发生变化时,通过调用<code>this.forceUpdate</code>触发组件的更新</li><li>一般情况下,我们在<code>componentDidMount</code>注册监听回调,在<code>componentWillUnmount</code>解除监听</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-onXzE" id="tab-RWRO7t4" checked="checked"><label for="tab-RWRO7t4">App.jsx</label><input type="radio" name="group-onXzE" id="tab-UdoGzK6"><label for="tab-UdoGzK6">index.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">App</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentDidMount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// Subscribe to the store</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">subscribe</span><span style="color:#E1E4E8;">(() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'subscribe'</span><span style="color:#E1E4E8;">, store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">forceUpdate</span><span style="color:#E1E4E8;">()</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentWillUnmount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">unsubscribe</span><span style="color:#E1E4E8;">()</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">>App</</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Count: {store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().count}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Name: {store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().name}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({ type: </span><span style="color:#9ECBFF;">'INCREMENT'</span><span style="color:#E1E4E8;"> })}> +1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({ type: </span><span style="color:#9ECBFF;">'DECREMENT'</span><span style="color:#E1E4E8;"> })}> -1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({ type: </span><span style="color:#9ECBFF;">'CHANGE_NAME'</span><span style="color:#E1E4E8;">, name: </span><span style="color:#9ECBFF;">'ZIU'</span><span style="color:#E1E4E8;"> })}></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> {</span><span style="color:#9ECBFF;">' '</span><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> CHANGE_NAME{</span><span style="color:#9ECBFF;">' '</span><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">App</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentDidMount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// Subscribe to the store</span></span>
|
||
<span class="line"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">subscribe</span><span style="color:#24292E;">(() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'subscribe'</span><span style="color:#24292E;">, store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">forceUpdate</span><span style="color:#24292E;">()</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentWillUnmount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">unsubscribe</span><span style="color:#24292E;">()</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">>App</</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Count: {store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().count}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Name: {store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().name}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({ type: </span><span style="color:#032F62;">'INCREMENT'</span><span style="color:#24292E;"> })}> +1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({ type: </span><span style="color:#032F62;">'DECREMENT'</span><span style="color:#24292E;"> })}> -1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({ type: </span><span style="color:#032F62;">'CHANGE_NAME'</span><span style="color:#24292E;">, name: </span><span style="color:#032F62;">'ZIU'</span><span style="color:#24292E;"> })}></span></span>
|
||
<span class="line"><span style="color:#24292E;"> {</span><span style="color:#032F62;">' '</span><span style="color:#24292E;">}</span></span>
|
||
<span class="line"><span style="color:#24292E;"> CHANGE_NAME{</span><span style="color:#032F62;">' '</span><span style="color:#24292E;">}</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// The initial application state</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// This is the same as the state argument we passed to the createStore function</span></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">initialState</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: </span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: </span><span style="color:#9ECBFF;">'Ziu'</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// Reducer: a pure function that takes the previous state and an action, and returns the next state.</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// (previousState, action) => newState</span></span>
|
||
<span class="line"><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">reducer</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> initialState, </span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'reducer'</span><span style="color:#E1E4E8;">, state, action)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">switch</span><span style="color:#E1E4E8;"> (action.type) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'INCREMENT'</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// NOTE: Keep functions pure - do not mutate the original state.</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// Desctructure the state object and return a **new object** with the updated count</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// Instead of \`return state.count++\`</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count </span><span style="color:#F97583;">+</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">1</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'DECREMENT'</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count </span><span style="color:#F97583;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">1</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'CHANGE_NAME'</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: action.name</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> state</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createStore</span><span style="color:#E1E4E8;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> store</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createStore } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// The initial application state</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// This is the same as the state argument we passed to the createStore function</span></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">initialState</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: </span><span style="color:#005CC5;">0</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: </span><span style="color:#032F62;">'Ziu'</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// Reducer: a pure function that takes the previous state and an action, and returns the next state.</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// (previousState, action) => newState</span></span>
|
||
<span class="line"><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">reducer</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> initialState, </span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'reducer'</span><span style="color:#24292E;">, state, action)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">switch</span><span style="color:#24292E;"> (action.type) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'INCREMENT'</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// NOTE: Keep functions pure - do not mutate the original state.</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// Desctructure the state object and return a **new object** with the updated count</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// Instead of \`return state.count++\`</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count </span><span style="color:#D73A49;">+</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">1</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'DECREMENT'</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count </span><span style="color:#D73A49;">-</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">1</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'CHANGE_NAME'</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: action.name</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> state</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br></div></div></div></div><p><img src="`+l+`" alt="redux-usage"></p><h2 id="进一步封装" tabindex="-1">进一步封装 <a class="header-anchor" href="#进一步封装" aria-label="Permalink to "进一步封装""></a></h2><p>可以将耦合在一起的代码拆分到不同文件中</p><ul><li>将<code>reducer</code>抽取出来<code>reducer.js</code>,简化<code>store/index.js</code>内容</li><li>将<code>action.type</code>抽取为常量<code>constants.js</code>,使用时做导入,以保证一致性</li><li>将<code>action</code>抽取出来<code>actionFactory.js</code>,用于外部dispatch时规范类型</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-C73w6" id="tab-4nDF_1u" checked="checked"><label for="tab-4nDF_1u">index.js</label><input type="radio" name="group-C73w6" id="tab-V9zNHuK"><label for="tab-V9zNHuK">constants.js</label><input type="radio" name="group-C73w6" id="tab-HejD2nv"><label for="tab-HejD2nv">reducer.js</label><input type="radio" name="group-C73w6" id="tab-P17NaIx"><label for="tab-P17NaIx">actionFactory.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> reducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createStore</span><span style="color:#E1E4E8;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> store</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createStore } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> reducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// constants.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">INCREMENT</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'INCREMENT'</span></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">DECREMENT</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'DECREMENT'</span></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">CHANGE_NAME</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'CHANGE_NAME'</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// constants.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">INCREMENT</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'INCREMENT'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">DECREMENT</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'DECREMENT'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">CHANGE_NAME</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'CHANGE_NAME'</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// reducer.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">*</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">as</span><span style="color:#E1E4E8;"> actionType </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">initialState</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: </span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: </span><span style="color:#9ECBFF;">'Ziu'</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">reducer</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> initialState, </span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">switch</span><span style="color:#E1E4E8;"> (action.type) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> actionType.</span><span style="color:#79B8FF;">INCREMENT</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count </span><span style="color:#F97583;">+</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">1</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> actionType.</span><span style="color:#79B8FF;">DECREMENT</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count </span><span style="color:#F97583;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">1</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> actionType.</span><span style="color:#79B8FF;">CHANGE_NAME</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: action.name</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;">:</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> state</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// reducer.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">*</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">as</span><span style="color:#24292E;"> actionType </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">initialState</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: </span><span style="color:#005CC5;">0</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: </span><span style="color:#032F62;">'Ziu'</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">reducer</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> initialState, </span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">switch</span><span style="color:#24292E;"> (action.type) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> actionType.</span><span style="color:#005CC5;">INCREMENT</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count </span><span style="color:#D73A49;">+</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">1</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> actionType.</span><span style="color:#005CC5;">DECREMENT</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count </span><span style="color:#D73A49;">-</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">1</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> actionType.</span><span style="color:#005CC5;">CHANGE_NAME</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: action.name</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;">:</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> state</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">*</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">as</span><span style="color:#E1E4E8;"> actionType </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">increment</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> type: actionType.</span><span style="color:#79B8FF;">INCREMENT</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">decrement</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> type: actionType.</span><span style="color:#79B8FF;">DECREMENT</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">changeName</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">name</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> type: actionType.</span><span style="color:#79B8FF;">CHANGE_NAME</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">*</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">as</span><span style="color:#24292E;"> actionType </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">increment</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> type: actionType.</span><span style="color:#005CC5;">INCREMENT</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">decrement</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> type: actionType.</span><span style="color:#005CC5;">DECREMENT</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">changeName</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">name</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> type: actionType.</span><span style="color:#005CC5;">CHANGE_NAME</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { increment, decrement, changeName } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store/actionFactory'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">App</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentDidMount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">subscribe</span><span style="color:#E1E4E8;">(() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">forceUpdate</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentWillUnmount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">unsubscribe</span><span style="color:#E1E4E8;">()</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">>App</</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Count: {store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().count}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Name: {store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().name}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">increment</span><span style="color:#E1E4E8;">())}> +1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">decrement</span><span style="color:#E1E4E8;">())}> -1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">changeName</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'ZIU'</span><span style="color:#E1E4E8;">))}>CHANGE_NAME</</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { increment, decrement, changeName } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store/actionFactory'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">App</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentDidMount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">subscribe</span><span style="color:#24292E;">(() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">forceUpdate</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentWillUnmount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">unsubscribe</span><span style="color:#24292E;">()</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">>App</</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Count: {store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().count}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Name: {store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().name}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">increment</span><span style="color:#24292E;">())}> +1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">decrement</span><span style="color:#24292E;">())}> -1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">changeName</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'ZIU'</span><span style="color:#24292E;">))}>CHANGE_NAME</</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h2 id="redux的三大原则" tabindex="-1">Redux的三大原则 <a class="header-anchor" href="#redux的三大原则" aria-label="Permalink to "Redux的三大原则""></a></h2><p>单一数据源</p><ul><li>整个应用程序的状态都被存储在一棵Object Tree上</li><li>且这个Object Tree只存储在一个Store中</li><li>但Redux并不强制限制创建多Store,不利于数据维护</li><li>单一数据源有利于整个应用程序的维护、追踪、修改</li></ul><p>State属性是只读的</p><ul><li>允许修改State的方法只有patch action,不要直接修改State</li><li>确保了View或网络请求都不能修改State</li><li>保证所有的修改都能被追踪、按照严格的顺序执行,不用担心竞态(race condition)的问题</li></ul><p>使用纯函数来执行修改</p><ul><li>通过reducer将旧State与新State联系在一起,并且返回一个<strong>新的State</strong></li><li>随着应用程序复杂程度增加,可以将reducer拆分为多个小的reducer,分别用于操作不同State Tree的某一部分</li><li>所有的reducer都应该是纯函数,不能产生任何的副作用</li></ul><h2 id="优化重复代码" tabindex="-1">优化重复代码 <a class="header-anchor" href="#优化重复代码" aria-label="Permalink to "优化重复代码""></a></h2><p>当编写了一些案例的时候会发现,React结合Redux时会编写很多重复的代码</p><p>在每个需要用到Redux中状态的组件中,都需要在不同生命周期做添加订阅/解除订阅的处理,组件初始化时还要从store中取最新的状态</p><p>针对重复代码的问题,可以使用之前学到的高阶组件来做优化</p><p>Redux官方提供的库<code>react-redux</code>,可以让我们更方便的在React中使用Redux</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>在Profile组件中,通过高阶函数<code>connect</code>实现的</p><p>将store中需要的状态通过<code>mapStoreToProps</code>转为props,并将需要使用store中状态的组件传入调用connect返回的函数中</p><p>在<code>Profile</code>组件中就可以从props中获取到store中的状态</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-ODkad" id="tab-oZ0KAqP" checked="checked"><label for="tab-oZ0KAqP">App.jsx</label><input type="radio" name="group-ODkad" id="tab-7kgd_xp"><label for="tab-7kgd_xp">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { Provider } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> Profile </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./Profile'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">App</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">Provider</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">store</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{store}></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">>App</</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">Profile</span><span style="color:#E1E4E8;">></</span><span style="color:#79B8FF;">Profile</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#79B8FF;">Provider</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { Provider } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> Profile </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./Profile'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">App</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#005CC5;">Provider</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">store</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{store}></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">>App</</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#005CC5;">Profile</span><span style="color:#24292E;">></</span><span style="color:#005CC5;">Profile</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#005CC5;">Provider</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { connect } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// mapStateToProps is a function that</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// takes the state of the store as an argument</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// and returns an object with the data that the component needs from the store.</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// component will receive the data as props.</span></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(mapStateToProps)(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Profile</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">>Profile</</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Count: {</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.count}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { connect } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// mapStateToProps is a function that</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// takes the state of the store as an argument</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// and returns an object with the data that the component needs from the store.</span></span>
|
||
<span class="line"><span style="color:#6A737D;">// component will receive the data as props.</span></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(mapStateToProps)(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Profile</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">>Profile</</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Count: {</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.count}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div></div></div><p>我们刚刚只是完成了对State的映射,将Store中保存的全局状态state映射到了Profile组件的props中</p><p>connect还可以传入第二个参数,用于将action也映射到props中:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { connect } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { INCREMENT, DECREMENT } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store/constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.count</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">increment</span><span style="color:#E1E4E8;">: () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({ type: </span><span style="color:#79B8FF;">INCREMENT</span><span style="color:#E1E4E8;"> }),</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">decrement</span><span style="color:#E1E4E8;">: () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({ type: </span><span style="color:#79B8FF;">DECREMENT</span><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapStateToProps,</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Profile</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">>Profile</</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">>Count: {</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.count}</</span><span style="color:#85E89D;">p</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.increment}> +1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.decrement}> -1 </</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { connect } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { INCREMENT, DECREMENT } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store/constants'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.count</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">increment</span><span style="color:#24292E;">: () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({ type: </span><span style="color:#005CC5;">INCREMENT</span><span style="color:#24292E;"> }),</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">decrement</span><span style="color:#24292E;">: () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({ type: </span><span style="color:#005CC5;">DECREMENT</span><span style="color:#24292E;"> })</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapStateToProps,</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#24292E;">)(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Profile</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">>Profile</</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">p</span><span style="color:#24292E;">>Count: {</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.count}</</span><span style="color:#22863A;">p</span><span style="color:#24292E;">></span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.increment}> +1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.decrement}> -1 </</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br></div></div><p>本质上是<code>connect</code>内部对操作进行了封装,把逻辑隐藏起来了:</p><ul><li>调用<code>connect</code>这个<strong>高阶函数</strong>,返回一个<strong>高阶组件</strong></li><li>为高阶组件传入映射目标组件,最后高阶组件返回一个新组件</li><li>新组件的props包含了来自Store中状态/dispatch的映射</li></ul><h2 id="异步action" tabindex="-1">异步Action <a class="header-anchor" href="#异步action" aria-label="Permalink to "异步Action""></a></h2><p>有些场景下,我们希望组件能够直接调用Store中的action来触发网络请求,并且获取到数据</p><p>但是dispatch只允许派发对象类型的Action,不能通过dispatch派发函数</p><p>可以通过中间件<code>redux-thunk</code>来对Redux做增强,让dispatch能够对函数进行派发</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">redux-thunk</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">redux-thunk</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>通过<code>applyMiddleware</code>引入<code>redux-thunk</code>这个中间件:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-3ETMT" id="tab-yFH0YoS" checked="checked"><label for="tab-yFH0YoS">index.js</label><input type="radio" name="group-3ETMT" id="tab-YkAYEAn"><label for="tab-YkAYEAn">actionFactory.js</label><input type="radio" name="group-3ETMT" id="tab-zkiCXWx"><label for="tab-zkiCXWx">list.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore, applyMiddleware } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> thunk </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux-thunk'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> reducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createStore</span><span style="color:#E1E4E8;">(reducer, </span><span style="color:#B392F0;">applyMiddleware</span><span style="color:#E1E4E8;">(thunk))</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> store</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createStore, applyMiddleware } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux'</span></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> thunk </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux-thunk'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> reducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer, </span><span style="color:#6F42C1;">applyMiddleware</span><span style="color:#24292E;">(thunk))</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetchPostList</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">getState</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetch</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#E1E4E8;">)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> .</span><span style="color:#B392F0;">then</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">res</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> res.</span><span style="color:#B392F0;">json</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> .</span><span style="color:#B392F0;">then</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">res</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> type: actionType.</span><span style="color:#79B8FF;">FETCH_POST_LIST</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> list: res</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetchPostList</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">, </span><span style="color:#E36209;">getState</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetch</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#24292E;">)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> .</span><span style="color:#6F42C1;">then</span><span style="color:#24292E;">((</span><span style="color:#E36209;">res</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> res.</span><span style="color:#6F42C1;">json</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> .</span><span style="color:#6F42C1;">then</span><span style="color:#24292E;">((</span><span style="color:#E36209;">res</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> type: actionType.</span><span style="color:#005CC5;">FETCH_POST_LIST</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> list: res</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// list.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { connect } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { fetchPostList } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store/actionFactory'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> list: state.list</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetchList</span><span style="color:#E1E4E8;">: () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">fetchPostList</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Profile</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">>List</</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.</span><span style="color:#B392F0;">fetchList</span><span style="color:#E1E4E8;">()}>Fetch List</</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> {</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.list.</span><span style="color:#79B8FF;">length</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">&&</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">ul</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> {</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.list.</span><span style="color:#B392F0;">map</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">item</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">li</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">key</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{item.id}>{item.title}</</span><span style="color:#85E89D;">li</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> ))}</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">ul</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )}</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// list.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { connect } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { fetchPostList } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store/actionFactory'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> list: state.list</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetchList</span><span style="color:#24292E;">: () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">fetchPostList</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#24292E;">)(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Profile</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">>List</</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.</span><span style="color:#6F42C1;">fetchList</span><span style="color:#24292E;">()}>Fetch List</</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> {</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.list.</span><span style="color:#005CC5;">length</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">&&</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">ul</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> {</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.list.</span><span style="color:#6F42C1;">map</span><span style="color:#24292E;">((</span><span style="color:#E36209;">item</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">li</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">key</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{item.id}>{item.title}</</span><span style="color:#22863A;">li</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> ))}</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">ul</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )}</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br></div></div></div></div><ul><li>这样就可以将网络请求的具体逻辑代码隐藏到Redux中</li><li>将网络请求归于状态管理的一部分</li><li>而不是书写在组件内,不利于维护,耦合度太高</li></ul><p><code>redux-thunk</code>是如何做到可以让我们发送异步请求的?</p><ul><li>默认情况下<code>dispatch(action)</code>的action必须为一个JS对象</li><li><code>redux-thunk</code>允许我们传入一个函数作为<code>action</code></li><li>函数会被调用,并且将<code>dispatch</code>函数和<code>getState</code>函数作为入参传递给这个函数action <ul><li><code>dispatch</code> 允许我们在这之后再次派发<code>action</code></li><li><code>getState</code> 允许我们之后的一些操作依赖原来的状态,可以获取到之前的状态</li></ul></li></ul><p>下图展示了从组件调用方法,触发patch到Redux接收patch、发送网络请求、更新state的全过程:</p><p><img src="`+o+`" alt="redux-async-action"></p><h2 id="拆分store" tabindex="-1">拆分Store <a class="header-anchor" href="#拆分store" aria-label="Permalink to "拆分Store""></a></h2><p>拆分Store带来的益处很多,便于多人协作、不同业务逻辑解耦等</p><p>在Redux中,拆分Store的本质是拆分不同的<code>reducer</code>函数,之前在使用<code>createStore</code>时,传入的就是<code>reducer</code>函数</p><p>之前的Store写法与用法:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> reducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createStore</span><span style="color:#E1E4E8;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().count</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().list</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createStore } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> reducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./reducer'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().count</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().list</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>拆分Store后的写法与用法:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore, combineReducers } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> counterReducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./counter'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> postListReducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">reducer</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">combineReducers</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> counter: counterReducer,</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createStore</span><span style="color:#E1E4E8;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().counter.count</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">().postList.count</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createStore, combineReducers } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> counterReducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./counter'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> postListReducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">reducer</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">combineReducers</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> counter: counterReducer,</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().counter.count</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">().postList.count</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>拆分为多个Reducer之后,需要首先<code>getState()</code>获取到整个状态树,随后指定获取到不同的模块中的状态</p><p>拆分后,不同模块下的文件是保持一致的:</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">store/</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># Store根目录</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">index.js</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># 导出 store 位置</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">counter/</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># Counter模块</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">constants.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">index.js</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># 统一导出</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">postList/</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># PostList模块</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">constants.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">index.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">-</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">...</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">store/</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># Store根目录</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">index.js</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># 导出 store 位置</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">counter/</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># Counter模块</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">constants.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">index.js</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># 统一导出</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">postList/</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># PostList模块</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">constants.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">index.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">-</span><span style="color:#24292E;"> </span><span style="color:#032F62;">...</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h3 id="combinereducer函数" tabindex="-1">combineReducer函数 <a class="header-anchor" href="#combinereducer函数" aria-label="Permalink to "combineReducer函数""></a></h3><p>前面拆分Store时用到了<code>combineReducer</code>函数,将多个模块reducer组合到一起,函数内部是如何处理的?</p><ul><li>将传入的reducers合并到一个对象中,最终返回一个<code>combination</code>函数(相当于未拆分时传给<code>createStore</code>的<code>reducer</code>函数)</li><li>在执行<code>combination</code>函数的过程中,它会通过判断前后返回的数据是否相同来决定返回之前的state还是新的state</li><li>新state会触发订阅者发生对应更新,而旧state可以有效地组织订阅者发生刷新</li></ul><p>下面简单写了一下<code>combineReducer</code>的实现原理</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// 使用</span></span>
|
||
<span class="line"><span style="color:#B392F0;">combineReducer</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> counter: combineReducer,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// 创建一个新的reducer</span></span>
|
||
<span class="line"><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">reducer</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> {}, </span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 返回一个对象 是Store的state</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> counter: </span><span style="color:#B392F0;">counterReducer</span><span style="color:#E1E4E8;">(state.counter, action),</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: </span><span style="color:#B392F0;">postListReducer</span><span style="color:#E1E4E8;">(state.postList, action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// 使用</span></span>
|
||
<span class="line"><span style="color:#6F42C1;">combineReducer</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> counter: combineReducer,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A737D;">// 创建一个新的reducer</span></span>
|
||
<span class="line"><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">reducer</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> {}, </span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 返回一个对象 是Store的state</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> counter: </span><span style="color:#6F42C1;">counterReducer</span><span style="color:#24292E;">(state.counter, action),</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: </span><span style="color:#6F42C1;">postListReducer</span><span style="color:#24292E;">(state.postList, action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="reduxtoolkit" tabindex="-1">ReduxToolkit <a class="header-anchor" href="#reduxtoolkit" aria-label="Permalink to "ReduxToolkit""></a></h2><ul><li>ReduxToolkit重构</li><li>ReduxToolkit异步</li><li>connect高阶组件</li><li>中间件的实现原理</li><li>React状态管理选择</li></ul><h2 id="认识reduxtoolkit" tabindex="-1">认识ReduxToolkit <a class="header-anchor" href="#认识reduxtoolkit" aria-label="Permalink to "认识ReduxToolkit""></a></h2><p>之前在使用<code>createStore</code>创建Store时会出现deprecated标识,推荐我们使用<code>@reduxjs/toolkit</code>包中的<code>configureStore</code>函数</p><p>Redux Toolkit是官方推荐编写Redux逻辑的方法</p><ul><li>在前面学习Redux时已经发现,Redux的逻辑编写过于繁琐、麻烦</li><li>代码分拆在不同模块中,存在大量重复代码</li><li>Redux Toolkit旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题</li><li>这个包常被称为:RTK</li></ul><h2 id="使用reduxtoolkit重写store" tabindex="-1">使用ReduxToolkit重写Store <a class="header-anchor" href="#使用reduxtoolkit重写store" aria-label="Permalink to "使用ReduxToolkit重写Store""></a></h2><p>Redux Toolkit依赖于react-redux包,所以需要同时安装这二者</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">@reduxjs/toolkit</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">@reduxjs/toolkit</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>Redux Toolkit的核心API主要是下述几个:</p><ul><li><code>configureStore</code> 包装createStore以提供简化的配置选项和良好的默认值 <ul><li>可以自动组合你的slice reducer 添加你提供的任何Redux中间件</li><li>默认包含redux-thunk,并启用Redux DevTools Extension</li></ul></li><li><code>createSlice</code> 创建切片 片段 <ul><li>接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有actions</li></ul></li><li><code>createAsyncThunk</code><ul><li>接受一个动作类型字符串和一个返回Promise的函数</li><li>并生成一个<code>pending / fullfilled / rejected</code>基于该承诺分派动作类型的thunk</li></ul></li></ul><p>写一个Demo:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-HJVxY" id="tab-lzeossW" checked="checked"><label for="tab-lzeossW">index.js</label><input type="radio" name="group-HJVxY" id="tab-Borz_tB"><label for="tab-Borz_tB">counter.js</label><input type="radio" name="group-HJVxY" id="tab-x3bUds7"><label for="tab-x3bUds7">Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { configureStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> counterSlice </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./features/counter'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">configureStore</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> reducer: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> counter: counterSlice</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> store</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { configureStore } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> counterSlice </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./features/counter'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">configureStore</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> reducer: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> counter: counterSlice</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/features/counter.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createSlice } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">counterSlice</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createSlice</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: </span><span style="color:#9ECBFF;">'counter'</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: </span><span style="color:#79B8FF;">0</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">addCount</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">payload</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> action</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.count </span><span style="color:#F97583;">+=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">subCount</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">payload</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> action</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.count </span><span style="color:#F97583;">-=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">actions</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">reducer</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> counterSlice</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">addCount</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">subCount</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> reducer</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/features/counter.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createSlice } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">counterSlice</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createSlice</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: </span><span style="color:#032F62;">'counter'</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: </span><span style="color:#005CC5;">0</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">addCount</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, </span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">payload</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> action</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.count </span><span style="color:#D73A49;">+=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">subCount</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, </span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">payload</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> action</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.count </span><span style="color:#D73A49;">-=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">actions</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">reducer</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> counterSlice</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">addCount</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">subCount</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> reducer</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// Counter.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { connect } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { addCount, subCount } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../store/features/counter'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> count: state.counter.count</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">increment</span><span style="color:#E1E4E8;">: (</span><span style="color:#FFAB70;">count</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">action</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">addCount</span><span style="color:#E1E4E8;">(count)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">decrement</span><span style="color:#E1E4E8;">: (</span><span style="color:#FFAB70;">count</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">action</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">subCount</span><span style="color:#E1E4E8;">(count)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Counter</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">count</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">>Counter</</span><span style="color:#85E89D;">h2</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">>count: {count}</</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.</span><span style="color:#B392F0;">increment</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">)}>+1</</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.</span><span style="color:#B392F0;">decrement</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">)}>-1</</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// Counter.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { connect } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { addCount, subCount } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'../store/features/counter'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> count: state.counter.count</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">increment</span><span style="color:#24292E;">: (</span><span style="color:#E36209;">count</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">action</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">addCount</span><span style="color:#24292E;">(count)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">decrement</span><span style="color:#24292E;">: (</span><span style="color:#E36209;">count</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">action</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">subCount</span><span style="color:#24292E;">(count)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#24292E;">)(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Counter</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">count</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">>Counter</</span><span style="color:#22863A;">h2</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">>count: {count}</</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.</span><span style="color:#6F42C1;">increment</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">)}>+1</</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.</span><span style="color:#6F42C1;">decrement</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">)}>-1</</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div></div></div><p><code>createSlice</code> 函数参数解读</p><ul><li><code>name</code> 标记Slice 展示在dev-tool中</li><li><code>initialState</code> 初始化状态</li><li><code>reducers</code> 对象 对应之前的reducer函数</li><li>返回值: 一个对象 包含所有actions</li></ul><p><code>configureStore</code> 解读</p><ul><li><code>reducer</code> 将slice中的reducer组成一个对象,传入此参数</li><li><code>middleware</code> 额外的中间件 <ul><li>RTK已经为我们集成了<code>redux-thunk</code>和<code>redux-devtool</code>两个中间件</li></ul></li><li><code>devTools</code> 布尔值 是否启用开发者工具</li></ul><h2 id="使用rtk执行异步dispatch" tabindex="-1">使用RTK执行异步dispatch <a class="header-anchor" href="#使用rtk执行异步dispatch" aria-label="Permalink to "使用RTK执行异步dispatch""></a></h2><p>实际场景中都是在组件中发起网络请求,并且将状态更新到Store中</p><p>之前的开发中,我们通过<code>redux-thunk</code>这个中间件,让dispatch中可以进行异步操作</p><p>ReduxToolkit默认已经给我们集成了Thunk相关的功能:<code>createAsyncThunk</code></p><p>下面我们使用RTK实现一下这个场景:在Profile中请求postList数据并保存在Store中,并展示出来</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-eD3hM" id="tab-WqRP6Kn" checked="checked"><label for="tab-WqRP6Kn">postList.js</label><input type="radio" name="group-eD3hM" id="tab-q24ewpz"><label for="tab-q24ewpz">index.js</label><input type="radio" name="group-eD3hM" id="tab-5Zqv3ZG"><label for="tab-5Zqv3ZG">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/features/postList.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createSlice, createAsyncThunk } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">fetchPostList</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createAsyncThunk</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetch/postList'</span><span style="color:#E1E4E8;">, </span><span style="color:#F97583;">async</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">url</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'https://jsonplaceholder.typicode.com/posts'</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">data</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">await</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetch</span><span style="color:#E1E4E8;">(url).</span><span style="color:#B392F0;">then</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">res</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> res.</span><span style="color:#B392F0;">json</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> data</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">postListSlice</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createSlice</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: </span><span style="color:#9ECBFF;">'postList'</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: []</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">setPostList</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.postList </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> extraReducers: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> [fetchPostList.fulfilled]: (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'payload'</span><span style="color:#E1E4E8;">, payload)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.postList </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> [fetchPostList.pending]: (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetchPostList.pending'</span><span style="color:#E1E4E8;">, payload)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> [fetchPostList.rejected]: (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetchPostList.rejected'</span><span style="color:#E1E4E8;">, payload)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">setPostList</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> postListSlice.actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> postListSlice.reducer</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/features/postList.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createSlice, createAsyncThunk } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">fetchPostList</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createAsyncThunk</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'fetch/postList'</span><span style="color:#24292E;">, </span><span style="color:#D73A49;">async</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">url</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'https://jsonplaceholder.typicode.com/posts'</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">data</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">await</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetch</span><span style="color:#24292E;">(url).</span><span style="color:#6F42C1;">then</span><span style="color:#24292E;">((</span><span style="color:#E36209;">res</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> res.</span><span style="color:#6F42C1;">json</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> data</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">postListSlice</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createSlice</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: </span><span style="color:#032F62;">'postList'</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: []</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">setPostList</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.postList </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> extraReducers: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> [fetchPostList.fulfilled]: (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'payload'</span><span style="color:#24292E;">, payload)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.postList </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> [fetchPostList.pending]: (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'fetchPostList.pending'</span><span style="color:#24292E;">, payload)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> [fetchPostList.rejected]: (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'fetchPostList.rejected'</span><span style="color:#24292E;">, payload)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">setPostList</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> postListSlice.actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> postListSlice.reducer</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { configureStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> counterReducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./features/counter'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> postListReducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./features/postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">configureStore</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> reducer: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> counter: counterReducer,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { configureStore } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> counterReducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./features/counter'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> postListReducer </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./features/postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">configureStore</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> reducer: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> counter: counterReducer,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: postListReducer</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { connect } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { fetchPostList } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../store/features/postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: state.postList.postList</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> ({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetchPostList</span><span style="color:#E1E4E8;">: () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">fetchPostList</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Profile</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> Profile</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">onClick</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.</span><span style="color:#B392F0;">fetchPostList</span><span style="color:#E1E4E8;">()}>Fetch Data</</span><span style="color:#85E89D;">button</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">ul</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> {</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props.postList.</span><span style="color:#B392F0;">map</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">item</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">index</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">li</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">key</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{index}>{item.title}</</span><span style="color:#85E89D;">li</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> ))}</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">ul</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { connect } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react-redux'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { fetchPostList } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'../store/features/postList'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: state.postList.postList</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> ({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetchPostList</span><span style="color:#24292E;">: () </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">fetchPostList</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapStateToProps,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#24292E;">)(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Profile</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> Profile</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">button</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">onClick</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.</span><span style="color:#6F42C1;">fetchPostList</span><span style="color:#24292E;">()}>Fetch Data</</span><span style="color:#22863A;">button</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">ul</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> {</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props.postList.</span><span style="color:#6F42C1;">map</span><span style="color:#24292E;">((</span><span style="color:#E36209;">item</span><span style="color:#24292E;">, </span><span style="color:#E36209;">index</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">li</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">key</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{index}>{item.title}</</span><span style="color:#22863A;">li</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> ))}</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">ul</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br></div></div></div></div><p>当<code>createAsyncThunk</code>创建出来的action被dispatch时,会存在三种状态:</p><ul><li>pending: action被发出,但是还没有最终的结果</li><li>fulfilled: 获取到最终的结果(有返回值的结果)</li><li>rejected: 执行过程中又错误或者抛出了异常</li></ul><p>我们可以在<code>createSlice</code>的<code>entraReducer</code>中监听这些结果,根据派发action后的状态添加不同的逻辑进行处理</p><p>除了上述的写法,还可以为<code>extraReducer</code>传入一个函数,函数接收一个<code>builder</code>作为参数,在函数体内添加不同的case来监听异步操作的结果:</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">...</span></span>
|
||
<span class="line"><span style="color:#B392F0;">extraReducers</span><span style="color:#E1E4E8;">: (</span><span style="color:#FFAB70;">builder</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> builder.</span><span style="color:#B392F0;">addCase</span><span style="color:#E1E4E8;">(fetchPostList.fulfilled, (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.postList </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> builder.</span><span style="color:#B392F0;">addCase</span><span style="color:#E1E4E8;">(fetchPostList.pending, (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetchPostList.pending'</span><span style="color:#E1E4E8;">, payload)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> builder.</span><span style="color:#B392F0;">addCase</span><span style="color:#E1E4E8;">(fetchPostList.rejected, (</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetchPostList.rejected'</span><span style="color:#E1E4E8;">, payload)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"><span style="color:#F97583;">...</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">...</span></span>
|
||
<span class="line"><span style="color:#6F42C1;">extraReducers</span><span style="color:#24292E;">: (</span><span style="color:#E36209;">builder</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> builder.</span><span style="color:#6F42C1;">addCase</span><span style="color:#24292E;">(fetchPostList.fulfilled, (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.postList </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> builder.</span><span style="color:#6F42C1;">addCase</span><span style="color:#24292E;">(fetchPostList.pending, (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'fetchPostList.pending'</span><span style="color:#24292E;">, payload)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> builder.</span><span style="color:#6F42C1;">addCase</span><span style="color:#24292E;">(fetchPostList.rejected, (</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'fetchPostList.rejected'</span><span style="color:#24292E;">, payload)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"><span style="color:#D73A49;">...</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>在之前的代码中,我们都是通过触发action后置的回调来更新state,那么有没有可能在请求完毕时确定性地更新store中的state?</p><p>可以当请求有结果了,在请求成功的回调中直接dispatch设置state的action</p><p>当我们通过dispatch触发异步action时可以传递额外的参数,这些参数可以在传入createAsyncThunk的回调函数的参数中获取到,同时也可以从函数的参数中获取到<code>dispatch</code>与<code>getState</code>函数,这样就可以在请求到数据后直接通过派发action的方式更新store中的state,下面是修改后的例子:</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createSlice, createAsyncThunk } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">fetchPostList</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createAsyncThunk</span><span style="color:#E1E4E8;">(</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'fetch/postList'</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">async</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">extraInfo</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">dispatch</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">getState</span><span style="color:#E1E4E8;"> }) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">url</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'https://jsonplaceholder.typicode.com/posts'</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">data</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">await</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fetch</span><span style="color:#E1E4E8;">(url).</span><span style="color:#B392F0;">then</span><span style="color:#E1E4E8;">((</span><span style="color:#FFAB70;">res</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> res.</span><span style="color:#B392F0;">json</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">setPostList</span><span style="color:#E1E4E8;">(data))</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">postListSlice</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createSlice</span><span style="color:#E1E4E8;">({</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> name: </span><span style="color:#9ECBFF;">'postList'</span><span style="color:#E1E4E8;">,</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> postList: []</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> },</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">setPostList</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">state</span><span style="color:#E1E4E8;">, { </span><span style="color:#FFAB70;">payload</span><span style="color:#E1E4E8;"> }) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> state.postList </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> payload</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> { </span><span style="color:#79B8FF;">setPostList</span><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> postListSlice.actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> postListSlice.reducer</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createSlice, createAsyncThunk } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'@reduxjs/toolkit'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">fetchPostList</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createAsyncThunk</span><span style="color:#24292E;">(</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#032F62;">'fetch/postList'</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#D73A49;">async</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">extraInfo</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">dispatch</span><span style="color:#24292E;">, </span><span style="color:#E36209;">getState</span><span style="color:#24292E;"> }) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">url</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'https://jsonplaceholder.typicode.com/posts'</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">data</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">await</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fetch</span><span style="color:#24292E;">(url).</span><span style="color:#6F42C1;">then</span><span style="color:#24292E;">((</span><span style="color:#E36209;">res</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> res.</span><span style="color:#6F42C1;">json</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">setPostList</span><span style="color:#24292E;">(data))</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">postListSlice</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createSlice</span><span style="color:#24292E;">({</span></span>
|
||
<span class="line"><span style="color:#24292E;"> name: </span><span style="color:#032F62;">'postList'</span><span style="color:#24292E;">,</span></span>
|
||
<span class="line"><span style="color:#24292E;"> initialState: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> postList: []</span></span>
|
||
<span class="line"><span style="color:#24292E;"> },</span></span>
|
||
<span class="line"><span style="color:#24292E;"> reducers: {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">setPostList</span><span style="color:#24292E;">(</span><span style="color:#E36209;">state</span><span style="color:#24292E;">, { </span><span style="color:#E36209;">payload</span><span style="color:#24292E;"> }) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> state.postList </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> payload</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">})</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> { </span><span style="color:#005CC5;">setPostList</span><span style="color:#24292E;"> } </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> postListSlice.actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> postListSlice.reducer</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><p>当然,此时异步action的状态已经不那么重要了,也就不必再<code>return data</code>了,除非你需要对异常状态做额外处理,仍然可以在<code>extraReducers</code>中添加异常处理回调</p><h2 id="redux-toolkit的数据不可变性" tabindex="-1">Redux Toolkit的数据不可变性 <a class="header-anchor" href="#redux-toolkit的数据不可变性" aria-label="Permalink to "Redux Toolkit的数据不可变性""></a></h2><p>Redux Toolkit本质是对之前繁琐的操作进行的一次封装</p><p>我们注意到:在之前reducer对state进行更新时,必须返回一个新的state才能触发修改<code>state = { ...state, count: count + 1 }</code>,但是经过Redux Toolkit的封装,我们只需要<code>state.count += 1</code>,直接对状态进行赋值就可以完成状态的更新</p><p>这是因为在RTK内部使用了<code>immutable.js</code>,数据不可变性</p><ul><li>在React开发中,我们总是强调数据的不可变性 <ul><li>无论是类组件中的state还是redux中管理的state</li><li>JS的编码过程里,数据的不可变性都是非常重要的</li></ul></li><li>所以在之前我们更新state时都是通过浅拷贝来完成的 <ul><li>但是浅拷贝也存在它的缺陷:</li><li>当对象过大时,进行浅拷贝会造成性能的浪费</li><li>浅拷贝后的新对象,其深层属性仍然是旧对象的引用</li></ul></li></ul><p>Redux Toolkit底层使用了<code>immerjs</code>库来保证数据的不可变性</p><p>immutablejs库的底层原理和使用方法:<a href="https://mp.weixin.qq.com/s/hfeCDCcodBCGS5GpedxCGg" target="_blank" rel="noreferrer">React系列十八 - Redux(四)state如何管理</a></p><p>为了节约内存,出现了新的算法<code>Persistent Data Structure</code>持久化数据结构/一致性数据结构</p><ul><li>用一种数据结构来保存数据</li><li>当数据被修改时,会返回一个新的对象,但是新的对象会尽可能复用之前的数据结构而不会对内存进行浪费</li><li>比如有一棵引用层级较深的树,当我们对其深层某个节点进行修改时,不会完全拷贝整棵树,而是在尽可能复用旧树结构的同时创建一棵新的树</li></ul><p>一图胜千言:</p><p><img src="`+e+`" alt="immutable"></p><h2 id="connect的实现原理" tabindex="-1">connect的实现原理 <a class="header-anchor" href="#connect的实现原理" aria-label="Permalink to "connect的实现原理""></a></h2><p>connect函数是<code>react-redux</code>提供的一个高阶函数,它返回一个高阶组件,用于将store中的state/dispatch映射为组件的props</p><p>下面一步一步手写一个connect函数,实现和库提供的connect一样的映射功能:</p><p>首先完成基本的代码搭建,connect函数接收两个参数<code>mapStateToProps</code> <code>mapDispatchToProps</code>返回一个高阶组件</p><p>所谓高阶组件,就是传入一个类组件,返回一个增强后的新的类组件:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">mapStateToProps</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">mapDispatchToProps</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">InnerComponent</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">WrapperComponent</span><span style="color:#E1E4E8;"> {</span><span style="color:#F97583;">...</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props} /></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span><span style="color:#E36209;">mapStateToProps</span><span style="color:#24292E;">, </span><span style="color:#E36209;">mapDispatchToProps</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">WrapperComponent</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">InnerComponent</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#005CC5;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props} /></span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>其中,<code>mapStateToProps</code>和<code>mapDispatchToProps</code>都是函数,函数入参是<code>state</code>与<code>dispatch</code>,返回一个对象,键值对对应<code>prop <=> state/dispatch调用</code></p><p>我们导入store,并且从store中获取到state和dispatch传入<code>mapStateToProps</code>和<code>mapDispatchToProps</code>,随后将得到的键值对以props形式传递给WrapperComponent</p><p>这样新组件就可以拿到这些状态与dispatch方法,我们可以在<code>componentDidMount</code>中监听整个store,当store中的状态发生改变时,强制执行re-render</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">mapStateToProps</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">mapDispatchToProps</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">InnerComponent</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentDidMount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">subscribe</span><span style="color:#E1E4E8;">(() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">forceUpdate</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">dispatch</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;">(store.dispatch)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">WrapperComponent</span><span style="color:#E1E4E8;"> {</span><span style="color:#F97583;">...</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props} {</span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state} {</span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">dispatch} /></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'../store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span><span style="color:#E36209;">mapStateToProps</span><span style="color:#24292E;">, </span><span style="color:#E36209;">mapDispatchToProps</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">WrapperComponent</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">InnerComponent</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentDidMount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">subscribe</span><span style="color:#24292E;">(() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">forceUpdate</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">dispatch</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;">(store.dispatch)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#005CC5;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props} {</span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state} {</span><span style="color:#D73A49;">...</span><span style="color:#24292E;">dispatch} /></span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>上述代码能够正常工作,但是显然每次store内state发生改变都re-render是不明智的,因为组件可能只用到了store中的某些状态</p><p>那些组件没有用到的其他状态发生改变时,组件不应该也跟着re-render,这里可以做一些优化</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">mapStateToProps</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">mapDispatchToProps</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">InnerComponent</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">constructor</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">props</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">super</span><span style="color:#E1E4E8;">(props)</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.state </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentDidMount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> store.</span><span style="color:#B392F0;">subscribe</span><span style="color:#E1E4E8;">(() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">setState</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">()))</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">dispatch</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;">(store.dispatch)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> <</span><span style="color:#B392F0;">WrapperComponent</span><span style="color:#E1E4E8;"> {</span><span style="color:#F97583;">...</span><span style="color:#B392F0;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">props</span><span style="color:#E1E4E8;">} {</span><span style="color:#F97583;">...</span><span style="color:#B392F0;">state</span><span style="color:#E1E4E8;">} {</span><span style="color:#F97583;">...</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">} /></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'../store'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span><span style="color:#E36209;">mapStateToProps</span><span style="color:#24292E;">, </span><span style="color:#E36209;">mapDispatchToProps</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">WrapperComponent</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">InnerComponent</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">constructor</span><span style="color:#24292E;">(</span><span style="color:#E36209;">props</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">super</span><span style="color:#24292E;">(props)</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.state </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentDidMount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> store.</span><span style="color:#6F42C1;">subscribe</span><span style="color:#24292E;">(() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">setState</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">()))</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">dispatch</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;">(store.dispatch)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#6F42C1;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">props</span><span style="color:#24292E;">} {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">state</span><span style="color:#24292E;">} {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">} /></span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><p>经过优化后,每次store.state发生变化会触发setState,由React内部的机制来决定组件是否应当重新渲染</p><p>如果组件依赖的state发生变化了,那么React会替我们执行re-render,而不是每次都强制执行re-render</p><p>进一步地,我们可以补充更多细节:</p><ul><li>当组件卸载时解除监听 <ul><li><code>store.subscribe</code>会返回一个<code>unsubscribe</code>函数 用于解除监听</li></ul></li><li>解除与业务代码store的耦合 <ul><li>目前的store来自业务代码 更优的做法是从context中动态获取到store</li><li>应当提供一个context Provider供用户使用</li><li>就像<code>react-redux</code>一样,使用connect前需要将App用Provider包裹并传入store</li></ul></li></ul><p>至此就基本完成了一个connect函数</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-vJVEc" id="tab-lsTZmck" checked="checked"><label for="tab-lsTZmck">connect.js</label><input type="radio" name="group-vJVEc" id="tab-cDwMIH5"><label for="tab-cDwMIH5">storeContext.js</label><input type="radio" name="group-vJVEc" id="tab-1NE8jYV"><label for="tab-1NE8jYV">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { StoreContext } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./storeContext'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">connect</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">mapStateToProps</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">mapDispatchToProps</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">InnerComponent</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">PureComponent</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">constructor</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">props</span><span style="color:#E1E4E8;">, </span><span style="color:#FFAB70;">context</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">super</span><span style="color:#E1E4E8;">(props)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.state </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(context.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentDidMount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.unsubscribe </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.context.</span><span style="color:#B392F0;">subscribe</span><span style="color:#E1E4E8;">(() </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">setState</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.context.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">()))</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">componentWillUnmount</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">unsubscribe</span><span style="color:#E1E4E8;">()</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">state</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapStateToProps</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.context.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">dispatch</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">mapDispatchToProps</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.context.dispatch)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">WrapperComponent</span><span style="color:#E1E4E8;"> {</span><span style="color:#F97583;">...</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.props} {</span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">state} {</span><span style="color:#F97583;">...</span><span style="color:#E1E4E8;">dispatch} /></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> InnerComponent.contextType </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> StoreContext</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> InnerComponent</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { PureComponent } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { StoreContext } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./storeContext'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">connect</span><span style="color:#24292E;">(</span><span style="color:#E36209;">mapStateToProps</span><span style="color:#24292E;">, </span><span style="color:#E36209;">mapDispatchToProps</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span><span style="color:#E36209;">WrapperComponent</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">InnerComponent</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">PureComponent</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">constructor</span><span style="color:#24292E;">(</span><span style="color:#E36209;">props</span><span style="color:#24292E;">, </span><span style="color:#E36209;">context</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">super</span><span style="color:#24292E;">(props)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.state </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(context.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentDidMount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.unsubscribe </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.context.</span><span style="color:#6F42C1;">subscribe</span><span style="color:#24292E;">(() </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">setState</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.context.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">()))</span></span>
|
||
<span class="line"><span style="color:#24292E;"> })</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">componentWillUnmount</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">unsubscribe</span><span style="color:#24292E;">()</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">state</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapStateToProps</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.context.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">dispatch</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">mapDispatchToProps</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.context.dispatch)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#005CC5;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.props} {</span><span style="color:#D73A49;">...</span><span style="color:#24292E;">state} {</span><span style="color:#D73A49;">...</span><span style="color:#24292E;">dispatch} /></span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> InnerComponent.contextType </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> StoreContext</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> InnerComponent</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// storeContext.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createContext } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">StoreContext</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createContext</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">null</span><span style="color:#E1E4E8;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Provider</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> StoreContext.Provider</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// storeContext.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { createContext } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">StoreContext</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createContext</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">null</span><span style="color:#24292E;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Provider</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> StoreContext.Provider</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { Component } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> Counter </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./cpns/Counter'</span></span>
|
||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { Provider } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./hoc'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">App</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">extends</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Component</span><span style="color:#E1E4E8;"> {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">render</span><span style="color:#E1E4E8;">() {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">Provider</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">value</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">{store}></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">>React Redux</</span><span style="color:#85E89D;">h1</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> <</span><span style="color:#79B8FF;">Counter</span><span style="color:#E1E4E8;"> /></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#85E89D;">div</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </</span><span style="color:#79B8FF;">Provider</span><span style="color:#E1E4E8;">></span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> )</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> React, { Component } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'react'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> store </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./store'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> Counter </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./cpns/Counter'</span></span>
|
||
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { Provider } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'./hoc'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">App</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">extends</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Component</span><span style="color:#24292E;"> {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">render</span><span style="color:#24292E;">() {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (</span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#005CC5;">Provider</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">value</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{store}></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">>React Redux</</span><span style="color:#22863A;">h1</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> <</span><span style="color:#005CC5;">Counter</span><span style="color:#24292E;"> /></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#005CC5;">Provider</span><span style="color:#24292E;">></span></span>
|
||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></div></div><h2 id="实现日志中间件logger" tabindex="-1">实现日志中间件logger <a class="header-anchor" href="#实现日志中间件logger" aria-label="Permalink to "实现日志中间件logger""></a></h2><p>设想现在有需求:设计一个Redux中间件,当我们每次通过dispatch派发action时都能够在控制台输出:派发了哪个action,传递的数据是怎样的</p><p>最终实现:拦截dispatch,并且在控制台打印派发的action</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// logger.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">logger</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">store</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">next</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> store.dispatch </span><span style="color:#6A737D;">// 保留原始的dispatch函数</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatchWithLog</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">group</span><span style="color:#E1E4E8;">(action.type)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'dispatching'</span><span style="color:#E1E4E8;">, action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">res</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> next.</span><span style="color:#B392F0;">dispatch</span><span style="color:#E1E4E8;">(action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">log</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'next state'</span><span style="color:#E1E4E8;">, store.</span><span style="color:#B392F0;">getState</span><span style="color:#E1E4E8;">())</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> console.</span><span style="color:#B392F0;">groupEnd</span><span style="color:#E1E4E8;">()</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> res</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> store.dispatch </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> dispatchWithLog</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#B392F0;">logger</span><span style="color:#E1E4E8;">(store) </span><span style="color:#6A737D;">// 应用中间件</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// logger.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">logger</span><span style="color:#24292E;">(</span><span style="color:#E36209;">store</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">next</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> store.dispatch </span><span style="color:#6A737D;">// 保留原始的dispatch函数</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatchWithLog</span><span style="color:#24292E;">(</span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">group</span><span style="color:#24292E;">(action.type)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'dispatching'</span><span style="color:#24292E;">, action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">res</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> next.</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">(action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">log</span><span style="color:#24292E;">(</span><span style="color:#032F62;">'next state'</span><span style="color:#24292E;">, store.</span><span style="color:#6F42C1;">getState</span><span style="color:#24292E;">())</span></span>
|
||
<span class="line"><span style="color:#24292E;"> console.</span><span style="color:#6F42C1;">groupEnd</span><span style="color:#24292E;">()</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> res</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> store.dispatch </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> dispatchWithLog</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6F42C1;">logger</span><span style="color:#24292E;">(store) </span><span style="color:#6A737D;">// 应用中间件</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>通过<code>monkey patch</code>对原始dispatch函数进行了修改,为函数添加额外的副作用</p><h2 id="实现redux-thunk" tabindex="-1">实现redux-thunk <a class="header-anchor" href="#实现redux-thunk" aria-label="Permalink to "实现redux-thunk""></a></h2><p><code>redux-thunk</code>这个库帮我们提供了派发异步函数的功能</p><p>回顾一下<code>redux-thunk</code>的功能:</p><ul><li>默认情况下dispatch(action)的action必须为一个JS对象</li><li>redux-thunk允许我们传入一个函数作为action</li><li>函数会被调用,并且将dispatch函数和getState函数作为入参传递给这个函数action <ul><li>dispatch 允许我们在这之后再次派发action</li><li>getState 允许我们之后的一些操作依赖原来的状态,可以获取到之前的状态</li></ul></li></ul><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// thunk.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">thunk</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">store</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">next</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> store.dispatch</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">dispatchWithThunk</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">action</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (</span><span style="color:#F97583;">typeof</span><span style="color:#E1E4E8;"> action </span><span style="color:#F97583;">===</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'function'</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// pass dispatch and getState to the thunk</span></span>
|
||
<span class="line highlighted"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">action</span><span style="color:#E1E4E8;">(store.dispatch, store.getState)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">next</span><span style="color:#E1E4E8;">(action)</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> dispatchWithThunk</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#B392F0;">thunk</span><span style="color:#E1E4E8;">(store) </span><span style="color:#6A737D;">// 应用中间件</span></span></code></pre><pre class="shiki github-light has-highlighted-lines vp-code-light"><code><span class="line"><span style="color:#6A737D;">// thunk.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">thunk</span><span style="color:#24292E;">(</span><span style="color:#E36209;">store</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">next</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> store.dispatch</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">dispatchWithThunk</span><span style="color:#24292E;">(</span><span style="color:#E36209;">action</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (</span><span style="color:#D73A49;">typeof</span><span style="color:#24292E;"> action </span><span style="color:#D73A49;">===</span><span style="color:#24292E;"> </span><span style="color:#032F62;">'function'</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// pass dispatch and getState to the thunk</span></span>
|
||
<span class="line highlighted"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">action</span><span style="color:#24292E;">(store.dispatch, store.getState)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">next</span><span style="color:#24292E;">(action)</span></span>
|
||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> dispatchWithThunk</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6F42C1;">thunk</span><span style="color:#24292E;">(store) </span><span style="color:#6A737D;">// 应用中间件</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>需要注意的是,传递给函数action的第一个参数是经过更新后的新的<code>dispatch</code>函数,这是从细节考虑:如果在函数中又派发了函数</p><h2 id="实现applymiddleware" tabindex="-1">实现applyMiddleware <a class="header-anchor" href="#实现applymiddleware" aria-label="Permalink to "实现applyMiddleware""></a></h2><p>当我们需要同时应用多个中间件时,可以用<code>applyMiddleware</code>来对多个中间件进行组合,统一进行注册</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// applyMiddleware.js</span></span>
|
||
<span class="line"><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">applyMiddleware</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">store</span><span style="color:#E1E4E8;">, </span><span style="color:#F97583;">...</span><span style="color:#FFAB70;">fns</span><span style="color:#E1E4E8;">) {</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;"> fns.</span><span style="color:#B392F0;">forEach</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">fn</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">fn</span><span style="color:#E1E4E8;">(store))</span></span>
|
||
<span class="line"><span style="color:#E1E4E8;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#B392F0;">applyMiddleware</span><span style="color:#E1E4E8;">(store, logger, thunk) </span><span style="color:#6A737D;">// 使用applyMiddleware</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// applyMiddleware.js</span></span>
|
||
<span class="line"><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">applyMiddleware</span><span style="color:#24292E;">(</span><span style="color:#E36209;">store</span><span style="color:#24292E;">, </span><span style="color:#D73A49;">...</span><span style="color:#E36209;">fns</span><span style="color:#24292E;">) {</span></span>
|
||
<span class="line"><span style="color:#24292E;"> fns.</span><span style="color:#6F42C1;">forEach</span><span style="color:#24292E;">(</span><span style="color:#E36209;">fn</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=></span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">fn</span><span style="color:#24292E;">(store))</span></span>
|
||
<span class="line"><span style="color:#24292E;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6F42C1;">applyMiddleware</span><span style="color:#24292E;">(store, logger, thunk) </span><span style="color:#6A737D;">// 使用applyMiddleware</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div>`,152),r=[c];function E(y,i,u,d,b,F){return n(),a("div",null,r)}const g=s(t,[["render",E]]);export{h as __pageData,g as default};
|