mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-18 15:39:35 +08:00
648 lines
243 KiB
JavaScript
648 lines
243 KiB
JavaScript
import{_ as s,o as n,c as a,R as l}from"./chunks/framework.abedd97e.js";const p="/assets/redux-usage.7df84df8.svg",o="/assets/redux-async-action.0dc40e11.svg",e="/assets/immutable.dc41f87b.gif",d=JSON.parse('{"title":"Redux","description":"","frontmatter":{},"headers":[],"relativePath":"note/Redux.md","filePath":"note/Redux.md","lastUpdated":1687752747000}'),t={name:"note/Redux.md"},c=l(`<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"><div class="tabs"><input type="radio" name="group-DOf6V" id="tab-2eMYeGg" checked="checked"><label for="tab-2eMYeGg">App.jsx</label><input type="radio" name="group-DOf6V" id="tab-oqdRfl3"><label for="tab-oqdRfl3">index.js</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">App</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">componentDidMount</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// Subscribe to the store</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">subscribe</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">subscribe</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">forceUpdate</span><span style="color:#F07178;">()</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">componentWillUnmount</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">unsubscribe</span><span style="color:#F07178;">()</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">App</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Count: </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Name: </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">INCREMENT</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> +1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">DECREMENT</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> -1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">CHANGE_NAME</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">ZIU</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> CHANGE_NAME</span><span style="color:#89DDFF;">{</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// The initial application state</span></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// This is the same as the state argument we passed to the createStore function</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> initialState </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// 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:#676E95;font-style:italic;">// (previousState, action) => newState</span></span>
|
||
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">reducer</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> initialState</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">reducer</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">switch</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">action</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">type</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">INCREMENT</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// NOTE: Keep functions pure - do not mutate the original state.</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// Desctructure the state object and return a **new object** with the updated count</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// Instead of \`return state.count++\`</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> count</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">DECREMENT</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> count</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">CHANGE_NAME</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> name</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> 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="`+p+`" 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"><div class="tabs"><input type="radio" name="group-z5rxY" id="tab-etP7JPs" checked="checked"><label for="tab-etP7JPs">index.js</label><input type="radio" name="group-z5rxY" id="tab-riml1gY"><label for="tab-riml1gY">constants.js</label><input type="radio" name="group-z5rxY" id="tab-o_fDbH1"><label for="tab-o_fDbH1">reducer.js</label><input type="radio" name="group-z5rxY" id="tab-pO3aNX_"><label for="tab-pO3aNX_">actionFactory.js</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> reducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./reducer</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> 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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// constants.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> INCREMENT </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">INCREMENT</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> DECREMENT </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">DECREMENT</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> CHANGE_NAME </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">CHANGE_NAME</span><span style="color:#89DDFF;">'</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// reducer.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">as</span><span style="color:#A6ACCD;"> actionType </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./constants</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> initialState </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">reducer</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> initialState</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">switch</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">action</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">type</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">INCREMENT</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> count</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">DECREMENT</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> count</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">CHANGE_NAME</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> name</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#89DDFF;">:</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">as</span><span style="color:#A6ACCD;"> actionType </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./constants</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> increment </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">INCREMENT</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> decrement </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">DECREMENT</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> changeName </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">name</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">CHANGE_NAME</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> name</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">increment</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">decrement</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">changeName</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store/actionFactory</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">App</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">componentDidMount</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">subscribe</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">forceUpdate</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">componentWillUnmount</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">unsubscribe</span><span style="color:#F07178;">()</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">App</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Count: </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Name: </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">increment</span><span style="color:#A6ACCD;">())</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> +1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">decrement</span><span style="color:#A6ACCD;">())</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> -1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">changeName</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">ZIU</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">))</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;">CHANGE_NAME</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">i</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">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"><div class="tabs"><input type="radio" name="group-sTWnW" id="tab-YYZ2ooh" checked="checked"><label for="tab-YYZ2ooh">App.jsx</label><input type="radio" name="group-sTWnW" id="tab-yCNcRd1"><label for="tab-yCNcRd1">Profile.jsx</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Provider</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> Profile </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./Profile</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">App</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">Provider</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">store</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">}></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">App</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">Profile</span><span style="color:#89DDFF;">></</span><span style="color:#FFCB6B;">Profile</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#FFCB6B;">Provider</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">connect</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// mapStateToProps is a function that</span></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// takes the state of the store as an argument</span></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// and returns an object with the data that the component needs from the store.</span></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// component will receive the data as props.</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapStateToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#A6ACCD;">(mapStateToProps)(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Profile</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Profile</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Count: </span><span style="color:#89DDFF;">{this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">connect</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">INCREMENT</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">DECREMENT</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store/constants</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapStateToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapDispatchToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">increment</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> INCREMENT </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">decrement</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">type</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> DECREMENT </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#A6ACCD;">(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapStateToProps</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Profile</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Profile</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Count: </span><span style="color:#89DDFF;">{this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">p</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">increment</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> +1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">decrement</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;"> -1 </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">i</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">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"><div class="tabs"><input type="radio" name="group-ixGIs" id="tab-dd2XZD5" checked="checked"><label for="tab-dd2XZD5">index.js</label><input type="radio" name="group-ixGIs" id="tab-kwQF69W"><label for="tab-kwQF69W">actionFactory.js</label><input type="radio" name="group-ixGIs" id="tab-t2HQ09N"><label for="tab-t2HQ09N">list.jsx</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">applyMiddleware</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> thunk </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux-thunk</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> reducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./reducer</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(reducer</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">applyMiddleware</span><span style="color:#A6ACCD;">(thunk))</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> 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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fetchPostList </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">getState</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">fetch</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">https://jsonplaceholder.typicode.com/posts</span><span style="color:#89DDFF;">'</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">res</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">json</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">res</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> type</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">actionType</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">FETCH_POST_LIST</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> list</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// list.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">connect</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store/actionFactory</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapStateToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">list</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">list</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapDispatchToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fetchList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">fetchPostList</span><span style="color:#A6ACCD;">())</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#A6ACCD;">(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapStateToProps</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Profile</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">List</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fetchList</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;">Fetch List</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">list</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length </span><span style="color:#89DDFF;">&&</span><span style="color:#A6ACCD;"> (</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">ul</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">list</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">map</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">li</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">key</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">item</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">id</span><span style="color:#89DDFF;">}>{</span><span style="color:#A6ACCD;">item</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">title</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">li</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> ))</span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">ul</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> )</span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> reducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./reducer</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createStore</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">combineReducers</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> counterReducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./counter</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> postListReducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./postList</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> reducer </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">combineReducers</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">counter</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> counterReducer</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> postListReducer</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createStore</span><span style="color:#A6ACCD;">(reducer)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">counter</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">store/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># Store根目录</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">index.js</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 导出 store 位置</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">counter/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># Counter模块</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">constants.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">index.js</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 统一导出</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">postList/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># PostList模块</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">actionFactory.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">constants.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">index.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">reducer.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">...</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 使用</span></span>
|
||
<span class="line"><span style="color:#82AAFF;">combineReducer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">counter</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> combineReducer</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> postListReducer</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// 创建一个新的reducer</span></span>
|
||
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">reducer</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{},</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// 返回一个对象 是Store的state</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> counter</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">counterReducer</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">counter</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> postList</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">postListReducer</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">npm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">i</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">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"><div class="tabs"><input type="radio" name="group-PTv-b" id="tab-32jW7i1" checked="checked"><label for="tab-32jW7i1">index.js</label><input type="radio" name="group-PTv-b" id="tab-GfvR3t7"><label for="tab-GfvR3t7">counter.js</label><input type="radio" name="group-PTv-b" id="tab-PcGrJYS"><label for="tab-PcGrJYS">Counter.jsx</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">configureStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> counterSlice </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./features/counter</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configureStore</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">reducer</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">counter</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> counterSlice</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> 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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/features/counter.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createSlice</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> counterSlice </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createSlice</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">counter</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">initialState</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">reducers</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">addCount</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">subCount</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> actions</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> reducer </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> counterSlice</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> addCount</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> subCount </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> 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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// Counter.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">connect</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">addCount</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">subCount</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">../store/features/counter</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapStateToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">count</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">counter</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">count</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapDispatchToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">increment</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">count</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">addCount</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">decrement</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">count</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">subCount</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#A6ACCD;">(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapStateToProps</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Counter</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">count</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">Counter</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h2</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">count: </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;">count</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">increment</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;">+1</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">decrement</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;">-1</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</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"><div class="tabs"><input type="radio" name="group-EwBAG" id="tab-lNdVLz9" checked="checked"><label for="tab-lNdVLz9">postList.js</label><input type="radio" name="group-EwBAG" id="tab-al_TjmA"><label for="tab-al_TjmA">index.js</label><input type="radio" name="group-EwBAG" id="tab-4zE5kpI"><label for="tab-4zE5kpI">Profile.jsx</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/features/postList.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createSlice</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createAsyncThunk</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fetchPostList </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createAsyncThunk</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetch/postList</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">url</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">https://jsonplaceholder.typicode.com/posts</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">fetch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">url</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">res</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">json</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span></span>
|
||
<span class="line highlighted"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> postListSlice </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createSlice</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">postList</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">initialState</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> []</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">reducers</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">setPostList</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">extraReducers</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">fulfilled</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">payload</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">pending</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetchPostList.pending</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">rejected</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetchPostList.rejected</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> setPostList </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> postListSlice</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> postListSlice</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// store/index.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">configureStore</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> counterReducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./features/counter</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> postListReducer </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./features/postList</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">configureStore</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">reducer</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">counter</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> counterReducer</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> postListReducer</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// Profile.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">connect</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react-redux</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">../store/features/postList</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapStateToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> mapDispatchToProps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">fetchPostList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">fetchPostList</span><span style="color:#A6ACCD;">())</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#A6ACCD;">(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapStateToProps</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> mapDispatchToProps</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Profile</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> Profile</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">onClick</span><span style="color:#89DDFF;">={()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">fetchPostList</span><span style="color:#A6ACCD;">()</span><span style="color:#89DDFF;">}></span><span style="color:#A6ACCD;">Fetch Data</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">button</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">ul</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">map</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">item</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">index</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">li</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">key</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">index</span><span style="color:#89DDFF;">}>{</span><span style="color:#A6ACCD;">item</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">title</span><span style="color:#89DDFF;">}</</span><span style="color:#F07178;">li</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> ))</span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">ul</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">...</span></span>
|
||
<span class="line"><span style="color:#FFCB6B;">extraReducers</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">builder</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">builder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addCase</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">fulfilled</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">})</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">builder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addCase</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">pending</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">})</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetchPostList.pending</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">builder</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addCase</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">fetchPostList</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">rejected</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">})</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetchPostList.rejected</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">...</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// postList.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createSlice</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createAsyncThunk</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">@reduxjs/toolkit</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fetchPostList </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createAsyncThunk</span><span style="color:#A6ACCD;">(</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">fetch/postList</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line highlighted"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">async</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">extraInfo</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">dispatch</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">getState</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">url</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">https://jsonplaceholder.typicode.com/posts</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">await</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">fetch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">url</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">then</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">res</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">json</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatch</span><span style="color:#F07178;">(</span><span style="color:#82AAFF;">setPostList</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;">))</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> postListSlice </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createSlice</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">postList</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">initialState</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">postList</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> []</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">},</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">reducers</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">setPostList</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">state</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">payload</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">})</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postList</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">payload</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> setPostList </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> postListSlice</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">actions</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> postListSlice</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">mapStateToProps</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">mapDispatchToProps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">WrapperComponent</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">class</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">InnerComponent</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">extends</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> render</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">WrapperComponent</span><span style="color:#89DDFF;"> {...this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">} /></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">../store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">mapStateToProps</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">mapDispatchToProps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">WrapperComponent</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">class</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">InnerComponent</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">extends</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> componentDidMount</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">subscribe</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">forceUpdate</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> render</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapDispatchToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">WrapperComponent</span><span style="color:#89DDFF;"> {...this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">} {...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">} {...</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#89DDFF;">} /></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">../store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">mapStateToProps</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">mapDispatchToProps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">WrapperComponent</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">class</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">InnerComponent</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">extends</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">super</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> componentDidMount</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">subscribe</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">setState</span><span style="color:#F07178;">(</span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">()))</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> render</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapDispatchToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">WrapperComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{...</span><span style="color:#FFCB6B;">this</span><span style="color:#89DDFF;">.</span><span style="color:#FFCB6B;">props</span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{...</span><span style="color:#FFCB6B;">state</span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{...</span><span style="color:#FFCB6B;">dispatch</span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> /</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> }</span></span>
|
||
<span class="line"><span style="color:#F07178;"> }</span></span>
|
||
<span class="line"><span style="color:#F07178;">}</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"><div class="tabs"><input type="radio" name="group-6doQ_" id="tab-RU5oY7w" checked="checked"><label for="tab-RU5oY7w">connect.js</label><input type="radio" name="group-6doQ_" id="tab--4QU9DK"><label for="tab--4QU9DK">storeContext.js</label><input type="radio" name="group-6doQ_" id="tab-2jstZ-S"><label for="tab-2jstZ-S">App.jsx</label></div><div class="blocks"><div class="language-tsx active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// connect.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">StoreContext</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./storeContext</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">connect</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">mapStateToProps</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">mapDispatchToProps</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">WrapperComponent</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">class</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">InnerComponent</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">extends</span><span style="color:#F07178;"> </span><span style="color:#FFCB6B;">PureComponent</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">constructor</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">props</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;font-style:italic;">context</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">super</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">props</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> componentDidMount</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">unsubscribe</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">subscribe</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">setState</span><span style="color:#F07178;">(</span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">()))</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> componentWillUnmount</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">unsubscribe</span><span style="color:#F07178;">()</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> render</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">state</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapStateToProps</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">mapDispatchToProps</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">this.</span><span style="color:#A6ACCD;">context</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">WrapperComponent</span><span style="color:#89DDFF;"> {...this.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">} {...</span><span style="color:#A6ACCD;">state</span><span style="color:#89DDFF;">} {...</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#89DDFF;">} /></span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">InnerComponent</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">contextType</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">StoreContext</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">InnerComponent</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// storeContext.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">createContext</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> StoreContext </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createContext</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">null</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> Provider </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> StoreContext</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// App.jsx</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> React</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Component</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">react</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> store </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./store</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> Counter </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./cpns/Counter</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Provider</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./hoc</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">class</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">App</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">extends</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">Component</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">render</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> (</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">Provider</span><span style="color:#89DDFF;"> </span><span style="color:#C792EA;">value</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">}></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">React Redux</span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">h1</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">Counter</span><span style="color:#89DDFF;"> /></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#F07178;">div</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></</span><span style="color:#FFCB6B;">Provider</span><span style="color:#89DDFF;">></span></span>
|
||
<span class="line"><span style="color:#F07178;"> )</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// logger.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">logger</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">store</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">next</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// 保留原始的dispatch函数</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">function</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatchWithLog</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">group</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">action</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">type</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">dispatching</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">next</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">dispatch</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">next state</span><span style="color:#89DDFF;">'</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getState</span><span style="color:#F07178;">())</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">groupEnd</span><span style="color:#F07178;">()</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">res</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dispatchWithLog</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#82AAFF;">logger</span><span style="color:#A6ACCD;">(store) </span><span style="color:#676E95;font-style:italic;">// 应用中间件</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight has-highlighted-lines"><code><span class="line"><span style="color:#676E95;font-style:italic;">// thunk.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">thunk</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">store</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">next</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">function</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">dispatchWithThunk</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">action</span><span style="color:#89DDFF;">)</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">typeof</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">function</span><span style="color:#89DDFF;">'</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// pass dispatch and getState to the thunk</span></span>
|
||
<span class="line highlighted"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">action</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">dispatch</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">store</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">getState</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">next</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">action</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">dispatchWithThunk</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#82AAFF;">thunk</span><span style="color:#A6ACCD;">(store) </span><span style="color:#676E95;font-style:italic;">// 应用中间件</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// applyMiddleware.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">applyMiddleware</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">store</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">...</span><span style="color:#A6ACCD;font-style:italic;">fns</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fns</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">forEach</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;font-style:italic;">fn</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">fn</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">store</span><span style="color:#F07178;">))</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#82AAFF;">applyMiddleware</span><span style="color:#A6ACCD;">(store</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> logger</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> thunk) </span><span style="color:#676E95;font-style:italic;">// 使用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 y(D,F,i,C,A,b){return n(),a("div",null,r)}const m=s(t,[["render",y]]);export{d as __pageData,m as default};
|