mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-17 23:19:55 +08:00
Deploying to gh-pages from @ ZiuChen/ZiuChen.github.io@931788551a 🚀
This commit is contained in:
parent
1a88dcb885
commit
d1a528ca31
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -78,7 +78,7 @@ import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.9b71bc06.js";const F=
|
||||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>另外,这里还有一个小技巧,在最末一个路由指定一个path为<code>*</code>的路由匹配规则,可以为路由匹配添加fallback策略,当未匹配到其之前的任何域名时,会展示NotFound页面</p><h2 id="嵌套路由" tabindex="-1">嵌套路由 <a class="header-anchor" href="#嵌套路由" aria-label="Permalink to "嵌套路由""></a></h2><p>嵌套路由可以通过在<code>Route</code>组件内部嵌套新的<code>Route</code>组件来实现</p><p>再通过<code>Outlet</code>组件来指定嵌套路由的占位元素(类似于VueRouter中的router-view)</p><p>我们在之前的例子的基础上,为Home页面添加两个子页面HomeRanking和HomeRecommand</p><p>同时,我们也应该为Home组件添加默认跳转,就像根路径默认重定向到Home组件那样,进入到Home组件后也应该默认重定向一个子页面中,这里我们仍然使用到了Navigate组件</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-qr84_" id="tab-LQf9XJe" checked="checked"><label for="tab-LQf9XJe">App.jsx </label><input type="radio" name="group-qr84_" id="tab-YrEa3ZT"><label for="tab-YrEa3ZT">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>另外,这里还有一个小技巧,在最末一个路由指定一个path为<code>*</code>的路由匹配规则,可以为路由匹配添加fallback策略,当未匹配到其之前的任何域名时,会展示NotFound页面</p><h2 id="嵌套路由" tabindex="-1">嵌套路由 <a class="header-anchor" href="#嵌套路由" aria-label="Permalink to "嵌套路由""></a></h2><p>嵌套路由可以通过在<code>Route</code>组件内部嵌套新的<code>Route</code>组件来实现</p><p>再通过<code>Outlet</code>组件来指定嵌套路由的占位元素(类似于VueRouter中的router-view)</p><p>我们在之前的例子的基础上,为Home页面添加两个子页面HomeRanking和HomeRecommand</p><p>同时,我们也应该为Home组件添加默认跳转,就像根路径默认重定向到Home组件那样,进入到Home组件后也应该默认重定向一个子页面中,这里我们仍然使用到了Navigate组件</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-QelV3" id="tab-Au3GXXa" checked="checked"><label for="tab-Au3GXXa">App.jsx </label><input type="radio" name="group-QelV3" id="tab-V6T5pxB"><label for="tab-V6T5pxB">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { Routes, Route, Navigate, NavLink } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-router-dom'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> Home </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./views/Home'</span></span>
|
||||
@ -148,7 +148,7 @@ import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.9b71bc06.js";const F=
|
||||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div></div></div><h2 id="编程式导航-高阶组件" tabindex="-1">编程式导航(高阶组件) <a class="header-anchor" href="#编程式导航-高阶组件" aria-label="Permalink to "编程式导航(高阶组件)""></a></h2><p>之前使用的ReactRouter提供的路由跳转的组件,无论是<code>Link</code>还是<code>NavLink</code>可定制化能力都比较差,无法实现“点击按钮后跳转路由”这样的需求,那么我们就需要通过编程式导航,使用JS来完成路由的跳转</p><p>ReactRouter提供了编程式导航的API:<code>useNavigate</code></p><p>自ReactRouter6起,编程式导航的API不再支持ClassComponent,全面拥抱Hooks。</p><p>我们将在后续的学习中开启Hooks的写法,那么目前如何在类组件中也能使用Hooks呢?答案是高阶组件</p><p>封装一个高阶组件<code>withRouter</code>,经过高阶组件处理的类组件的props将会携带router对象,上面包含一些我们需要的属性和方法:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-o9vL8" id="tab-6dUMmFl" checked="checked"><label for="tab-6dUMmFl">withRouter.js</label><input type="radio" name="group-o9vL8" id="tab-mKtCLe_"><label for="tab-mKtCLe_">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div></div></div><h2 id="编程式导航-高阶组件" tabindex="-1">编程式导航(高阶组件) <a class="header-anchor" href="#编程式导航-高阶组件" aria-label="Permalink to "编程式导航(高阶组件)""></a></h2><p>之前使用的ReactRouter提供的路由跳转的组件,无论是<code>Link</code>还是<code>NavLink</code>可定制化能力都比较差,无法实现“点击按钮后跳转路由”这样的需求,那么我们就需要通过编程式导航,使用JS来完成路由的跳转</p><p>ReactRouter提供了编程式导航的API:<code>useNavigate</code></p><p>自ReactRouter6起,编程式导航的API不再支持ClassComponent,全面拥抱Hooks。</p><p>我们将在后续的学习中开启Hooks的写法,那么目前如何在类组件中也能使用Hooks呢?答案是高阶组件</p><p>封装一个高阶组件<code>withRouter</code>,经过高阶组件处理的类组件的props将会携带router对象,上面包含一些我们需要的属性和方法:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-iqCHo" id="tab-a4yNUWC" checked="checked"><label for="tab-a4yNUWC">withRouter.js</label><input type="radio" name="group-iqCHo" id="tab-7QGrygn"><label for="tab-7QGrygn">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { useNavigate } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-router-dom'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">withRouter</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) {</span></span>
|
||||
@ -202,7 +202,7 @@ import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.9b71bc06.js";const F=
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div></div></div><p>我们使用<code>withRouter</code>高阶组件对Home组件进行了增强,可以通过编程式导航来实现二级路由跳转</p><p>这里只是展示了编程式导航的用法和高阶组件的能力,目前还是尽可能使用Hooks写法编写新项目</p><h2 id="动态路由-路由传参" tabindex="-1">动态路由(路由传参) <a class="header-anchor" href="#动态路由-路由传参" aria-label="Permalink to "动态路由(路由传参)""></a></h2><p>传递参数由两种方式:</p><ul><li>动态路由的方式</li><li>查询字符串传递参数</li></ul><p>动态路由是指:路由中的<strong>路径</strong>信息并不会固定</p><ul><li>比如匹配规则为<code>/detail/:id</code>时,<code>/detail/123</code> <code>detail/888</code>都会被匹配上,并将<code>123/888</code>作为id参数传递</li><li>其中<code>/detail/:id</code>这个匹配规则被称为动态路由</li></ul><p>动态路由常见于嵌套路由跳转,比如:从歌曲列表页面点击后跳转到歌曲详情页,可以通过路由传递歌曲的ID,访问到不同歌曲的详情页</p><p>我们在之前的HomeRanking榜单中加入列表和点击跳转功能,并编写一个新的组件Detail来接收来自路由的参数</p><p>同样地,<code>react-router-dom</code>为我们提供了从路由获取参数的API:<code>useParams</code>,它是一个Hooks,我们将它应用到之前编写的高级组件<code>withRouter</code>中</p><ul><li>在使用了<code>withRouter</code>的组件中,就可以通过<code>this.props.router.params.xxx</code>获取到当前路由中传递的参数</li><li>使用动态匹配路由时,传递给Route组件的<code>path</code>属性为<code>:xxx</code>,这里是<code>/detail/:id</code></li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-ieL2z" id="tab-Ym14233" checked="checked"><label for="tab-Ym14233">withRouter.js</label><input type="radio" name="group-ieL2z" id="tab-LvW-1QK"><label for="tab-LvW-1QK">HomeRanking.jsx</label><input type="radio" name="group-ieL2z" id="tab-GS6otG7"><label for="tab-GS6otG7">Detail.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div></div></div><p>我们使用<code>withRouter</code>高阶组件对Home组件进行了增强,可以通过编程式导航来实现二级路由跳转</p><p>这里只是展示了编程式导航的用法和高阶组件的能力,目前还是尽可能使用Hooks写法编写新项目</p><h2 id="动态路由-路由传参" tabindex="-1">动态路由(路由传参) <a class="header-anchor" href="#动态路由-路由传参" aria-label="Permalink to "动态路由(路由传参)""></a></h2><p>传递参数由两种方式:</p><ul><li>动态路由的方式</li><li>查询字符串传递参数</li></ul><p>动态路由是指:路由中的<strong>路径</strong>信息并不会固定</p><ul><li>比如匹配规则为<code>/detail/:id</code>时,<code>/detail/123</code> <code>detail/888</code>都会被匹配上,并将<code>123/888</code>作为id参数传递</li><li>其中<code>/detail/:id</code>这个匹配规则被称为动态路由</li></ul><p>动态路由常见于嵌套路由跳转,比如:从歌曲列表页面点击后跳转到歌曲详情页,可以通过路由传递歌曲的ID,访问到不同歌曲的详情页</p><p>我们在之前的HomeRanking榜单中加入列表和点击跳转功能,并编写一个新的组件Detail来接收来自路由的参数</p><p>同样地,<code>react-router-dom</code>为我们提供了从路由获取参数的API:<code>useParams</code>,它是一个Hooks,我们将它应用到之前编写的高级组件<code>withRouter</code>中</p><ul><li>在使用了<code>withRouter</code>的组件中,就可以通过<code>this.props.router.params.xxx</code>获取到当前路由中传递的参数</li><li>使用动态匹配路由时,传递给Route组件的<code>path</code>属性为<code>:xxx</code>,这里是<code>/detail/:id</code></li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-ToPv4" id="tab-n8TLRyJ" checked="checked"><label for="tab-n8TLRyJ">withRouter.js</label><input type="radio" name="group-ToPv4" id="tab-7ayA1qJ"><label for="tab-7ayA1qJ">HomeRanking.jsx</label><input type="radio" name="group-ToPv4" id="tab-qaVjkDP"><label for="tab-qaVjkDP">Detail.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { useNavigate, useParams } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-router-dom'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">withRouter</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">WrapperComponent</span><span style="color:#E1E4E8;">) {</span></span>
|
||||
@ -332,7 +332,7 @@ import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.9b71bc06.js";const F=
|
||||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">router</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> { navigate, params, query }</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#005CC5;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#24292E;">props} </span><span style="color:#6F42C1;">router</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">{router} /></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>需要注意的是,这里的<code>useSearchParams</code>是一个Hooks的常见形态</p><p>它返回一个数组,数组的首位为值,数组的次位为改变值的方法</p><p>与对象解构不同的是,数组结构是对位解构:保证位置一致则值一致,命名随意</p><p>而对象解构恰恰相反,不必保证位置,而需要保证命名一致</p></div><h2 id="路由的配置方式" tabindex="-1">路由的配置方式 <a class="header-anchor" href="#路由的配置方式" aria-label="Permalink to "路由的配置方式""></a></h2><p>至此为止,路由的配置是耦合在<code>App.jsx</code>中的,我们可以将Routes这部分代码抽离出单独的组件,也可以通过配置的方式来完成路由映射关系的编写</p><ul><li>在ReactRouter5版本中,我们可以将路由的映射规则写为JS对象,需要引入第三方库<code>react-router-config</code></li><li>在ReactRouter6版本中,允许我们将其写为配置文件,不需要安装其他内容</li></ul><p>6版本为我们提供了一个API:<code>useRoutes</code>,将我们编写的配置文件传入此函数,可以将其转化为之前编写的组件结构,本质上也是一种语法糖</p><p>需要注意的是,Hooks只能在函数式组件中使用,这里我们将App组件改用FunctionComponent书写了</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group--PmaF" id="tab-1RrmCKp" checked="checked"><label for="tab-1RrmCKp">index.js</label><input type="radio" name="group--PmaF" id="tab-6liOL3R"><label for="tab-6liOL3R">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// router/index.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>需要注意的是,这里的<code>useSearchParams</code>是一个Hooks的常见形态</p><p>它返回一个数组,数组的首位为值,数组的次位为改变值的方法</p><p>与对象解构不同的是,数组结构是对位解构:保证位置一致则值一致,命名随意</p><p>而对象解构恰恰相反,不必保证位置,而需要保证命名一致</p></div><h2 id="路由的配置方式" tabindex="-1">路由的配置方式 <a class="header-anchor" href="#路由的配置方式" aria-label="Permalink to "路由的配置方式""></a></h2><p>至此为止,路由的配置是耦合在<code>App.jsx</code>中的,我们可以将Routes这部分代码抽离出单独的组件,也可以通过配置的方式来完成路由映射关系的编写</p><ul><li>在ReactRouter5版本中,我们可以将路由的映射规则写为JS对象,需要引入第三方库<code>react-router-config</code></li><li>在ReactRouter6版本中,允许我们将其写为配置文件,不需要安装其他内容</li></ul><p>6版本为我们提供了一个API:<code>useRoutes</code>,将我们编写的配置文件传入此函数,可以将其转化为之前编写的组件结构,本质上也是一种语法糖</p><p>需要注意的是,Hooks只能在函数式组件中使用,这里我们将App组件改用FunctionComponent书写了</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-I0pYs" id="tab-bCsm4RB" checked="checked"><label for="tab-bCsm4RB">index.js</label><input type="radio" name="group-I0pYs" id="tab-WS47ErC"><label for="tab-WS47ErC">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// router/index.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { Navigate } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-router-dom'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> Home </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../views/Home'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> HomeRanking </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'../views/HomeRanking'</span></span>
|
@ -2050,7 +2050,7 @@ import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.9b71bc06.js";const p=
|
||||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><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><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br></div></div><h2 id="context跨组件传参" tabindex="-1">Context跨组件传参 <a class="header-anchor" href="#context跨组件传参" aria-label="Permalink to "Context跨组件传参""></a></h2><p>非父子组件之间的数据共享</p><ul><li>props层层传递 跨组件会很不方便 对于中间那些本不需要这些props数据的组件是冗余的</li><li>第三方状态库 外置于React 如Redux (实际开发中较为常用)</li><li>事件总线 ...</li></ul><p>针对跨组件传参的场景,React提供了一个API名为Context</p><ul><li>Context 提供了一个在组件之间共享此类值的方式,而不是显式地通过组件树逐层传递props</li><li>使用 Context 共享那些全局的数据,如主题色、用户登录状态、locales等</li></ul><h3 id="用context实现跨组件传参" tabindex="-1">用Context实现跨组件传参 <a class="header-anchor" href="#用context实现跨组件传参" aria-label="Permalink to "用Context实现跨组件传参""></a></h3><p>假设有App Profile UserCard三个嵌套组件,我们希望App中的 <code>isDarkMode</code> 状态能够透传到UserCard组件中</p><ul><li>全局通过 <code>createContext</code> 创建一个上下文</li><li>根组件通过 <code>DarkModeContext.Provider</code> 标签与 <code>value</code> 传递值到上下文中</li><li>需要使用到该值的子组件通过 <code>UserCard.contextType = DarkModeContext</code> 绑定到上下文</li><li>随后即可在子组件中通过 <code>this.context</code> 获取到此上下文当前绑定的状态值</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-GV0Ty" id="tab-23UPHic" checked="checked"><label for="tab-23UPHic">context.js</label><input type="radio" name="group-GV0Ty" id="tab-FB0WkOX"><label for="tab-FB0WkOX">App.jsx</label><input type="radio" name="group-GV0Ty" id="tab-H7Srwm1"><label for="tab-H7Srwm1">UserCard.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// context.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br></div></div><h2 id="context跨组件传参" tabindex="-1">Context跨组件传参 <a class="header-anchor" href="#context跨组件传参" aria-label="Permalink to "Context跨组件传参""></a></h2><p>非父子组件之间的数据共享</p><ul><li>props层层传递 跨组件会很不方便 对于中间那些本不需要这些props数据的组件是冗余的</li><li>第三方状态库 外置于React 如Redux (实际开发中较为常用)</li><li>事件总线 ...</li></ul><p>针对跨组件传参的场景,React提供了一个API名为Context</p><ul><li>Context 提供了一个在组件之间共享此类值的方式,而不是显式地通过组件树逐层传递props</li><li>使用 Context 共享那些全局的数据,如主题色、用户登录状态、locales等</li></ul><h3 id="用context实现跨组件传参" tabindex="-1">用Context实现跨组件传参 <a class="header-anchor" href="#用context实现跨组件传参" aria-label="Permalink to "用Context实现跨组件传参""></a></h3><p>假设有App Profile UserCard三个嵌套组件,我们希望App中的 <code>isDarkMode</code> 状态能够透传到UserCard组件中</p><ul><li>全局通过 <code>createContext</code> 创建一个上下文</li><li>根组件通过 <code>DarkModeContext.Provider</code> 标签与 <code>value</code> 传递值到上下文中</li><li>需要使用到该值的子组件通过 <code>UserCard.contextType = DarkModeContext</code> 绑定到上下文</li><li>随后即可在子组件中通过 <code>this.context</code> 获取到此上下文当前绑定的状态值</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-0zkWc" id="tab-r6-T3mD" checked="checked"><label for="tab-r6-T3mD">context.js</label><input type="radio" name="group-0zkWc" id="tab-Fn8Thaz"><label for="tab-Fn8Thaz">App.jsx</label><input type="radio" name="group-0zkWc" id="tab-Ejv9YVD"><label for="tab-Ejv9YVD">UserCard.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// context.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createContext } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">DarkModeContext</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createContext</span><span style="color:#E1E4E8;">()</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// context.js</span></span>
|
@ -1,4 +1,4 @@
|
||||
import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l="/assets/redux-usage.7df84df8.svg",o="/assets/redux-async-action.0dc40e11.svg",e="/assets/immutable.dc41f87b.gif",h=JSON.parse('{"title":"Redux","description":"","frontmatter":{},"headers":[],"relativePath":"note/Redux.md","filePath":"note/Redux.md","lastUpdated":1704524259000}'),t={name:"note/Redux.md"},c=p(`<h1 id="redux" tabindex="-1">Redux <a class="header-anchor" href="#redux" aria-label="Permalink to "Redux""></a></h1><h2 id="理解javascript的纯函数" tabindex="-1">理解JavaScript的纯函数 <a class="header-anchor" href="#理解javascript的纯函数" aria-label="Permalink to "理解JavaScript的纯函数""></a></h2><ul><li>函数式编程中有一个非常重要的概念 <strong>纯函数</strong>,JavaScript符合函数式编程的范式,所以也有纯函数的概念 <ul><li>在React开发中,纯函数被多次提及:</li><li>React组件被要求像一个纯函数(为什么是像,因为还有类组件)</li><li>Redux中有一个reducer的概念,同样是要求必须是一个纯函数</li></ul></li><li>掌握纯函数对于理解很多框架的设计都是有帮助的</li></ul><p>一个纯函数必然具备以下特征:</p><ul><li>确定的输入一定产生确定的输出</li><li>函数的执行过程中,不能产生副作用</li></ul><h2 id="为什么需要redux" tabindex="-1">为什么需要Redux <a class="header-anchor" href="#为什么需要redux" aria-label="Permalink to "为什么需要Redux""></a></h2><ul><li>JS需要管理的状态越来越多,越来越复杂</li><li>状态不断发生变化之间又相互依赖,这要求视图层也能同步更新</li><li>React提供了自动更新视图的方法,但状态仍需要手动管理</li><li>Redux可以帮我们管理状态,提供了<strong>可预测的状态管理</strong></li><li>框架无关,体积只有2KB大小</li></ul><h2 id="redux的核心理念" tabindex="-1">Redux的核心理念 <a class="header-anchor" href="#redux的核心理念" aria-label="Permalink to "Redux的核心理念""></a></h2><p>Redux的核心理念 Store</p><ul><li>定义一个统一的规范来操作数据,这样就可以做到对数据的跟踪</li><li><code>list.push()</code> <code>list[0].age = 18</code></li></ul><p>Redux的核心理念 Action</p><ul><li>Redux要求:要修改数据,必须通过Action来修改</li><li>所有数据的变化,必须通过派发(Patch)Action来更新</li><li>Action是一个普通的JS对象,用来描述此次更新的type与content</li><li><code>const action = { type: 'ADD_ITEM', item: { name: 'Ziu', age: 18 } }</code></li></ul><p>Redux的核心理念 Reducer</p><ul><li>如何将Store和Action联系在一起?</li><li>reducer是一个纯函数</li><li>完成的工作就是:将传入的state和action结合起来,生成一个新的state</li><li><code>patch</code> => <code>reducer</code> => <code>newState</code> => <code>Store</code></li></ul><h2 id="redux-demo" tabindex="-1">Redux Demo <a class="header-anchor" href="#redux-demo" aria-label="Permalink to "Redux Demo""></a></h2><p>下例中,通过<code>createStore</code>创建了一个Store(已经不推荐了)</p><ul><li>initialState用于在调用<code>createStore</code>时作为默认值传入<code>reducer</code></li><li>后续每次<code>store.dispatch</code>都会调用<code>reducer</code></li><li>通过<code>reducer</code>更新state中的数据</li></ul><p>在React中,可以通过<code>store.subscribe</code>注册State变化的监听回调</p><ul><li>当state发生变化时,通过调用<code>this.forceUpdate</code>触发组件的更新</li><li>一般情况下,我们在<code>componentDidMount</code>注册监听回调,在<code>componentWillUnmount</code>解除监听</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-1HRT7" id="tab-uHQfOzo" checked="checked"><label for="tab-uHQfOzo">App.jsx</label><input type="radio" name="group-1HRT7" id="tab-vXSjU8p"><label for="tab-vXSjU8p">index.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l="/assets/redux-usage.7df84df8.svg",o="/assets/redux-async-action.0dc40e11.svg",e="/assets/immutable.dc41f87b.gif",h=JSON.parse('{"title":"Redux","description":"","frontmatter":{},"headers":[],"relativePath":"note/Redux.md","filePath":"note/Redux.md","lastUpdated":1704524259000}'),t={name:"note/Redux.md"},c=p(`<h1 id="redux" tabindex="-1">Redux <a class="header-anchor" href="#redux" aria-label="Permalink to "Redux""></a></h1><h2 id="理解javascript的纯函数" tabindex="-1">理解JavaScript的纯函数 <a class="header-anchor" href="#理解javascript的纯函数" aria-label="Permalink to "理解JavaScript的纯函数""></a></h2><ul><li>函数式编程中有一个非常重要的概念 <strong>纯函数</strong>,JavaScript符合函数式编程的范式,所以也有纯函数的概念 <ul><li>在React开发中,纯函数被多次提及:</li><li>React组件被要求像一个纯函数(为什么是像,因为还有类组件)</li><li>Redux中有一个reducer的概念,同样是要求必须是一个纯函数</li></ul></li><li>掌握纯函数对于理解很多框架的设计都是有帮助的</li></ul><p>一个纯函数必然具备以下特征:</p><ul><li>确定的输入一定产生确定的输出</li><li>函数的执行过程中,不能产生副作用</li></ul><h2 id="为什么需要redux" tabindex="-1">为什么需要Redux <a class="header-anchor" href="#为什么需要redux" aria-label="Permalink to "为什么需要Redux""></a></h2><ul><li>JS需要管理的状态越来越多,越来越复杂</li><li>状态不断发生变化之间又相互依赖,这要求视图层也能同步更新</li><li>React提供了自动更新视图的方法,但状态仍需要手动管理</li><li>Redux可以帮我们管理状态,提供了<strong>可预测的状态管理</strong></li><li>框架无关,体积只有2KB大小</li></ul><h2 id="redux的核心理念" tabindex="-1">Redux的核心理念 <a class="header-anchor" href="#redux的核心理念" aria-label="Permalink to "Redux的核心理念""></a></h2><p>Redux的核心理念 Store</p><ul><li>定义一个统一的规范来操作数据,这样就可以做到对数据的跟踪</li><li><code>list.push()</code> <code>list[0].age = 18</code></li></ul><p>Redux的核心理念 Action</p><ul><li>Redux要求:要修改数据,必须通过Action来修改</li><li>所有数据的变化,必须通过派发(Patch)Action来更新</li><li>Action是一个普通的JS对象,用来描述此次更新的type与content</li><li><code>const action = { type: 'ADD_ITEM', item: { name: 'Ziu', age: 18 } }</code></li></ul><p>Redux的核心理念 Reducer</p><ul><li>如何将Store和Action联系在一起?</li><li>reducer是一个纯函数</li><li>完成的工作就是:将传入的state和action结合起来,生成一个新的state</li><li><code>patch</code> => <code>reducer</code> => <code>newState</code> => <code>Store</code></li></ul><h2 id="redux-demo" tabindex="-1">Redux Demo <a class="header-anchor" href="#redux-demo" aria-label="Permalink to "Redux Demo""></a></h2><p>下例中,通过<code>createStore</code>创建了一个Store(已经不推荐了)</p><ul><li>initialState用于在调用<code>createStore</code>时作为默认值传入<code>reducer</code></li><li>后续每次<code>store.dispatch</code>都会调用<code>reducer</code></li><li>通过<code>reducer</code>更新state中的数据</li></ul><p>在React中,可以通过<code>store.subscribe</code>注册State变化的监听回调</p><ul><li>当state发生变化时,通过调用<code>this.forceUpdate</code>触发组件的更新</li><li>一般情况下,我们在<code>componentDidMount</code>注册监听回调,在<code>componentWillUnmount</code>解除监听</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-A1yjD" id="tab-y5saWGa" checked="checked"><label for="tab-y5saWGa">App.jsx</label><input type="radio" name="group-A1yjD" id="tab-uaXfkNE"><label for="tab-uaXfkNE">index.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||||
<span class="line"></span>
|
||||
@ -144,7 +144,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">store</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">createStore</span><span style="color:#24292E;">(reducer)</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br></div></div></div></div><p><img src="`+l+`" alt="redux-usage"></p><h2 id="进一步封装" tabindex="-1">进一步封装 <a class="header-anchor" href="#进一步封装" aria-label="Permalink to "进一步封装""></a></h2><p>可以将耦合在一起的代码拆分到不同文件中</p><ul><li>将<code>reducer</code>抽取出来<code>reducer.js</code>,简化<code>store/index.js</code>内容</li><li>将<code>action.type</code>抽取为常量<code>constants.js</code>,使用时做导入,以保证一致性</li><li>将<code>action</code>抽取出来<code>actionFactory.js</code>,用于外部dispatch时规范类型</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-hwmmz" id="tab-tgQAaFS" checked="checked"><label for="tab-tgQAaFS">index.js</label><input type="radio" name="group-hwmmz" id="tab-ldfntgs"><label for="tab-ldfntgs">constants.js</label><input type="radio" name="group-hwmmz" id="tab-pRcVY6Q"><label for="tab-pRcVY6Q">reducer.js</label><input type="radio" name="group-hwmmz" id="tab-6AKIe3Z"><label for="tab-6AKIe3Z">actionFactory.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> store</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br></div></div></div></div><p><img src="`+l+`" alt="redux-usage"></p><h2 id="进一步封装" tabindex="-1">进一步封装 <a class="header-anchor" href="#进一步封装" aria-label="Permalink to "进一步封装""></a></h2><p>可以将耦合在一起的代码拆分到不同文件中</p><ul><li>将<code>reducer</code>抽取出来<code>reducer.js</code>,简化<code>store/index.js</code>内容</li><li>将<code>action.type</code>抽取为常量<code>constants.js</code>,使用时做导入,以保证一致性</li><li>将<code>action</code>抽取出来<code>actionFactory.js</code>,用于外部dispatch时规范类型</li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-YtH4J" id="tab-UIquh8G" checked="checked"><label for="tab-UIquh8G">index.js</label><input type="radio" name="group-YtH4J" id="tab-IjfAqsZ"><label for="tab-IjfAqsZ">constants.js</label><input type="radio" name="group-YtH4J" id="tab-lB2j1nn"><label for="tab-lB2j1nn">reducer.js</label><input type="radio" name="group-YtH4J" id="tab-3tuVrzL"><label for="tab-3tuVrzL">actionFactory.js</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> reducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./reducer'</span></span>
|
||||
<span class="line"></span>
|
||||
@ -294,7 +294,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"><span style="color:#24292E;"> </</span><span style="color:#22863A;">div</span><span style="color:#24292E;">></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h2 id="redux的三大原则" tabindex="-1">Redux的三大原则 <a class="header-anchor" href="#redux的三大原则" aria-label="Permalink to "Redux的三大原则""></a></h2><p>单一数据源</p><ul><li>整个应用程序的状态都被存储在一棵Object Tree上</li><li>且这个Object Tree只存储在一个Store中</li><li>但Redux并不强制限制创建多Store,不利于数据维护</li><li>单一数据源有利于整个应用程序的维护、追踪、修改</li></ul><p>State属性是只读的</p><ul><li>允许修改State的方法只有patch action,不要直接修改State</li><li>确保了View或网络请求都不能修改State</li><li>保证所有的修改都能被追踪、按照严格的顺序执行,不用担心竞态(race condition)的问题</li></ul><p>使用纯函数来执行修改</p><ul><li>通过reducer将旧State与新State联系在一起,并且返回一个<strong>新的State</strong></li><li>随着应用程序复杂程度增加,可以将reducer拆分为多个小的reducer,分别用于操作不同State Tree的某一部分</li><li>所有的reducer都应该是纯函数,不能产生任何的副作用</li></ul><h2 id="优化重复代码" tabindex="-1">优化重复代码 <a class="header-anchor" href="#优化重复代码" aria-label="Permalink to "优化重复代码""></a></h2><p>当编写了一些案例的时候会发现,React结合Redux时会编写很多重复的代码</p><p>在每个需要用到Redux中状态的组件中,都需要在不同生命周期做添加订阅/解除订阅的处理,组件初始化时还要从store中取最新的状态</p><p>针对重复代码的问题,可以使用之前学到的高阶组件来做优化</p><p>Redux官方提供的库<code>react-redux</code>,可以让我们更方便的在React中使用Redux</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>在Profile组件中,通过高阶函数<code>connect</code>实现的</p><p>将store中需要的状态通过<code>mapStoreToProps</code>转为props,并将需要使用store中状态的组件传入调用connect返回的函数中</p><p>在<code>Profile</code>组件中就可以从props中获取到store中的状态</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-CeOyg" id="tab-fShgliP" checked="checked"><label for="tab-fShgliP">App.jsx</label><input type="radio" name="group-CeOyg" id="tab-JPucDWZ"><label for="tab-JPucDWZ">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h2 id="redux的三大原则" tabindex="-1">Redux的三大原则 <a class="header-anchor" href="#redux的三大原则" aria-label="Permalink to "Redux的三大原则""></a></h2><p>单一数据源</p><ul><li>整个应用程序的状态都被存储在一棵Object Tree上</li><li>且这个Object Tree只存储在一个Store中</li><li>但Redux并不强制限制创建多Store,不利于数据维护</li><li>单一数据源有利于整个应用程序的维护、追踪、修改</li></ul><p>State属性是只读的</p><ul><li>允许修改State的方法只有patch action,不要直接修改State</li><li>确保了View或网络请求都不能修改State</li><li>保证所有的修改都能被追踪、按照严格的顺序执行,不用担心竞态(race condition)的问题</li></ul><p>使用纯函数来执行修改</p><ul><li>通过reducer将旧State与新State联系在一起,并且返回一个<strong>新的State</strong></li><li>随着应用程序复杂程度增加,可以将reducer拆分为多个小的reducer,分别用于操作不同State Tree的某一部分</li><li>所有的reducer都应该是纯函数,不能产生任何的副作用</li></ul><h2 id="优化重复代码" tabindex="-1">优化重复代码 <a class="header-anchor" href="#优化重复代码" aria-label="Permalink to "优化重复代码""></a></h2><p>当编写了一些案例的时候会发现,React结合Redux时会编写很多重复的代码</p><p>在每个需要用到Redux中状态的组件中,都需要在不同生命周期做添加订阅/解除订阅的处理,组件初始化时还要从store中取最新的状态</p><p>针对重复代码的问题,可以使用之前学到的高阶组件来做优化</p><p>Redux官方提供的库<code>react-redux</code>,可以让我们更方便的在React中使用Redux</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>在Profile组件中,通过高阶函数<code>connect</code>实现的</p><p>将store中需要的状态通过<code>mapStoreToProps</code>转为props,并将需要使用store中状态的组件传入调用connect返回的函数中</p><p>在<code>Profile</code>组件中就可以从props中获取到store中的状态</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-hEva0" id="tab-xFee9TL" checked="checked"><label for="tab-xFee9TL">App.jsx</label><input type="radio" name="group-hEva0" id="tab-2MpqYh5"><label for="tab-2MpqYh5">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> React, { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { Provider } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react-redux'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> store </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./store'</span></span>
|
||||
@ -434,7 +434,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br></div></div><p>本质上是<code>connect</code>内部对操作进行了封装,把逻辑隐藏起来了:</p><ul><li>调用<code>connect</code>这个<strong>高阶函数</strong>,返回一个<strong>高阶组件</strong></li><li>为高阶组件传入映射目标组件,最后高阶组件返回一个新组件</li><li>新组件的props包含了来自Store中状态/dispatch的映射</li></ul><h2 id="异步action" tabindex="-1">异步Action <a class="header-anchor" href="#异步action" aria-label="Permalink to "异步Action""></a></h2><p>有些场景下,我们希望组件能够直接调用Store中的action来触发网络请求,并且获取到数据</p><p>但是dispatch只允许派发对象类型的Action,不能通过dispatch派发函数</p><p>可以通过中间件<code>redux-thunk</code>来对Redux做增强,让dispatch能够对函数进行派发</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">redux-thunk</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">redux-thunk</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>通过<code>applyMiddleware</code>引入<code>redux-thunk</code>这个中间件:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-XVLOZ" id="tab-gZ3Mwb0" checked="checked"><label for="tab-gZ3Mwb0">index.js</label><input type="radio" name="group-XVLOZ" id="tab-MwYKlEp"><label for="tab-MwYKlEp">actionFactory.js</label><input type="radio" name="group-XVLOZ" id="tab-xDCi3n-"><label for="tab-xDCi3n-">list.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br></div></div><p>本质上是<code>connect</code>内部对操作进行了封装,把逻辑隐藏起来了:</p><ul><li>调用<code>connect</code>这个<strong>高阶函数</strong>,返回一个<strong>高阶组件</strong></li><li>为高阶组件传入映射目标组件,最后高阶组件返回一个新组件</li><li>新组件的props包含了来自Store中状态/dispatch的映射</li></ul><h2 id="异步action" tabindex="-1">异步Action <a class="header-anchor" href="#异步action" aria-label="Permalink to "异步Action""></a></h2><p>有些场景下,我们希望组件能够直接调用Store中的action来触发网络请求,并且获取到数据</p><p>但是dispatch只允许派发对象类型的Action,不能通过dispatch派发函数</p><p>可以通过中间件<code>redux-thunk</code>来对Redux做增强,让dispatch能够对函数进行派发</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">redux-thunk</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">redux-thunk</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>通过<code>applyMiddleware</code>引入<code>redux-thunk</code>这个中间件:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-DNdvw" id="tab-NZlATWu" checked="checked"><label for="tab-NZlATWu">index.js</label><input type="radio" name="group-DNdvw" id="tab-nM2iCcK"><label for="tab-nM2iCcK">actionFactory.js</label><input type="radio" name="group-DNdvw" id="tab-aLPhszE"><label for="tab-aLPhszE">list.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line highlighted"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createStore, applyMiddleware } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux'</span></span>
|
||||
<span class="line highlighted"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> thunk </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'redux-thunk'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> reducer </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./reducer'</span></span>
|
||||
@ -634,7 +634,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"><span style="color:#24292E;"> counter: </span><span style="color:#6F42C1;">counterReducer</span><span style="color:#24292E;">(state.counter, action),</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> postList: </span><span style="color:#6F42C1;">postListReducer</span><span style="color:#24292E;">(state.postList, action)</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="reduxtoolkit" tabindex="-1">ReduxToolkit <a class="header-anchor" href="#reduxtoolkit" aria-label="Permalink to "ReduxToolkit""></a></h2><ul><li>ReduxToolkit重构</li><li>ReduxToolkit异步</li><li>connect高阶组件</li><li>中间件的实现原理</li><li>React状态管理选择</li></ul><h2 id="认识reduxtoolkit" tabindex="-1">认识ReduxToolkit <a class="header-anchor" href="#认识reduxtoolkit" aria-label="Permalink to "认识ReduxToolkit""></a></h2><p>之前在使用<code>createStore</code>创建Store时会出现deprecated标识,推荐我们使用<code>@reduxjs/toolkit</code>包中的<code>configureStore</code>函数</p><p>Redux Toolkit是官方推荐编写Redux逻辑的方法</p><ul><li>在前面学习Redux时已经发现,Redux的逻辑编写过于繁琐、麻烦</li><li>代码分拆在不同模块中,存在大量重复代码</li><li>Redux Toolkit旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题</li><li>这个包常被称为:RTK</li></ul><h2 id="使用reduxtoolkit重写store" tabindex="-1">使用ReduxToolkit重写Store <a class="header-anchor" href="#使用reduxtoolkit重写store" aria-label="Permalink to "使用ReduxToolkit重写Store""></a></h2><p>Redux Toolkit依赖于react-redux包,所以需要同时安装这二者</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">@reduxjs/toolkit</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">@reduxjs/toolkit</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>Redux Toolkit的核心API主要是下述几个:</p><ul><li><code>configureStore</code> 包装createStore以提供简化的配置选项和良好的默认值 <ul><li>可以自动组合你的slice reducer 添加你提供的任何Redux中间件</li><li>默认包含redux-thunk,并启用Redux DevTools Extension</li></ul></li><li><code>createSlice</code> 创建切片 片段 <ul><li>接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有actions</li></ul></li><li><code>createAsyncThunk</code><ul><li>接受一个动作类型字符串和一个返回Promise的函数</li><li>并生成一个<code>pending / fullfilled / rejected</code>基于该承诺分派动作类型的thunk</li></ul></li></ul><p>写一个Demo:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-po-Wt" id="tab-fOqVXEN" checked="checked"><label for="tab-fOqVXEN">index.js</label><input type="radio" name="group-po-Wt" id="tab-gtI95gn"><label for="tab-gtI95gn">counter.js</label><input type="radio" name="group-po-Wt" id="tab-REk2vx2"><label for="tab-REk2vx2">Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="reduxtoolkit" tabindex="-1">ReduxToolkit <a class="header-anchor" href="#reduxtoolkit" aria-label="Permalink to "ReduxToolkit""></a></h2><ul><li>ReduxToolkit重构</li><li>ReduxToolkit异步</li><li>connect高阶组件</li><li>中间件的实现原理</li><li>React状态管理选择</li></ul><h2 id="认识reduxtoolkit" tabindex="-1">认识ReduxToolkit <a class="header-anchor" href="#认识reduxtoolkit" aria-label="Permalink to "认识ReduxToolkit""></a></h2><p>之前在使用<code>createStore</code>创建Store时会出现deprecated标识,推荐我们使用<code>@reduxjs/toolkit</code>包中的<code>configureStore</code>函数</p><p>Redux Toolkit是官方推荐编写Redux逻辑的方法</p><ul><li>在前面学习Redux时已经发现,Redux的逻辑编写过于繁琐、麻烦</li><li>代码分拆在不同模块中,存在大量重复代码</li><li>Redux Toolkit旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题</li><li>这个包常被称为:RTK</li></ul><h2 id="使用reduxtoolkit重写store" tabindex="-1">使用ReduxToolkit重写Store <a class="header-anchor" href="#使用reduxtoolkit重写store" aria-label="Permalink to "使用ReduxToolkit重写Store""></a></h2><p>Redux Toolkit依赖于react-redux包,所以需要同时安装这二者</p><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">npm</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">i</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">@reduxjs/toolkit</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">react-redux</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">npm</span><span style="color:#24292E;"> </span><span style="color:#032F62;">i</span><span style="color:#24292E;"> </span><span style="color:#032F62;">@reduxjs/toolkit</span><span style="color:#24292E;"> </span><span style="color:#032F62;">react-redux</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>Redux Toolkit的核心API主要是下述几个:</p><ul><li><code>configureStore</code> 包装createStore以提供简化的配置选项和良好的默认值 <ul><li>可以自动组合你的slice reducer 添加你提供的任何Redux中间件</li><li>默认包含redux-thunk,并启用Redux DevTools Extension</li></ul></li><li><code>createSlice</code> 创建切片 片段 <ul><li>接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有actions</li></ul></li><li><code>createAsyncThunk</code><ul><li>接受一个动作类型字符串和一个返回Promise的函数</li><li>并生成一个<code>pending / fullfilled / rejected</code>基于该承诺分派动作类型的thunk</li></ul></li></ul><p>写一个Demo:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-jtcvd" id="tab-xI-6-No" checked="checked"><label for="tab-xI-6-No">index.js</label><input type="radio" name="group-jtcvd" id="tab-9ovDM7s"><label for="tab-9ovDM7s">counter.js</label><input type="radio" name="group-jtcvd" id="tab-VVnPsk8"><label for="tab-VVnPsk8">Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/index.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { configureStore } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> counterSlice </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./features/counter'</span></span>
|
||||
<span class="line"></span>
|
||||
@ -778,7 +778,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"><span style="color:#24292E;"> )</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div></div></div><p><code>createSlice</code> 函数参数解读</p><ul><li><code>name</code> 标记Slice 展示在dev-tool中</li><li><code>initialState</code> 初始化状态</li><li><code>reducers</code> 对象 对应之前的reducer函数</li><li>返回值: 一个对象 包含所有actions</li></ul><p><code>configureStore</code> 解读</p><ul><li><code>reducer</code> 将slice中的reducer组成一个对象,传入此参数</li><li><code>middleware</code> 额外的中间件 <ul><li>RTK已经为我们集成了<code>redux-thunk</code>和<code>redux-devtool</code>两个中间件</li></ul></li><li><code>devTools</code> 布尔值 是否启用开发者工具</li></ul><h2 id="使用rtk执行异步dispatch" tabindex="-1">使用RTK执行异步dispatch <a class="header-anchor" href="#使用rtk执行异步dispatch" aria-label="Permalink to "使用RTK执行异步dispatch""></a></h2><p>实际场景中都是在组件中发起网络请求,并且将状态更新到Store中</p><p>之前的开发中,我们通过<code>redux-thunk</code>这个中间件,让dispatch中可以进行异步操作</p><p>ReduxToolkit默认已经给我们集成了Thunk相关的功能:<code>createAsyncThunk</code></p><p>下面我们使用RTK实现一下这个场景:在Profile中请求postList数据并保存在Store中,并展示出来</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-YyCWn" id="tab-Jg7kx3J" checked="checked"><label for="tab-Jg7kx3J">postList.js</label><input type="radio" name="group-YyCWn" id="tab--1jZS3r"><label for="tab--1jZS3r">index.js</label><input type="radio" name="group-YyCWn" id="tab-ywrBC6-"><label for="tab-ywrBC6-">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/features/postList.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div></div></div><p><code>createSlice</code> 函数参数解读</p><ul><li><code>name</code> 标记Slice 展示在dev-tool中</li><li><code>initialState</code> 初始化状态</li><li><code>reducers</code> 对象 对应之前的reducer函数</li><li>返回值: 一个对象 包含所有actions</li></ul><p><code>configureStore</code> 解读</p><ul><li><code>reducer</code> 将slice中的reducer组成一个对象,传入此参数</li><li><code>middleware</code> 额外的中间件 <ul><li>RTK已经为我们集成了<code>redux-thunk</code>和<code>redux-devtool</code>两个中间件</li></ul></li><li><code>devTools</code> 布尔值 是否启用开发者工具</li></ul><h2 id="使用rtk执行异步dispatch" tabindex="-1">使用RTK执行异步dispatch <a class="header-anchor" href="#使用rtk执行异步dispatch" aria-label="Permalink to "使用RTK执行异步dispatch""></a></h2><p>实际场景中都是在组件中发起网络请求,并且将状态更新到Store中</p><p>之前的开发中,我们通过<code>redux-thunk</code>这个中间件,让dispatch中可以进行异步操作</p><p>ReduxToolkit默认已经给我们集成了Thunk相关的功能:<code>createAsyncThunk</code></p><p>下面我们使用RTK实现一下这个场景:在Profile中请求postList数据并保存在Store中,并展示出来</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-9ECyv" id="tab-fnCEXL6" checked="checked"><label for="tab-fnCEXL6">postList.js</label><input type="radio" name="group-9ECyv" id="tab-9Wg-aCt"><label for="tab-9Wg-aCt">index.js</label><input type="radio" name="group-9ECyv" id="tab-1fdv3ZK"><label for="tab-1fdv3ZK">Profile.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark has-highlighted-lines vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// store/features/postList.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { createSlice, createAsyncThunk } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'@reduxjs/toolkit'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line highlighted"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">fetchPostList</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">createAsyncThunk</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">'fetch/postList'</span><span style="color:#E1E4E8;">, </span><span style="color:#F97583;">async</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=></span><span style="color:#E1E4E8;"> {</span></span>
|
||||
@ -1114,7 +1114,7 @@ import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.9b71bc06.js";const l=
|
||||
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> <</span><span style="color:#6F42C1;">WrapperComponent</span><span style="color:#24292E;"> {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">this</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">props</span><span style="color:#24292E;">} {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">state</span><span style="color:#24292E;">} {</span><span style="color:#D73A49;">...</span><span style="color:#6F42C1;">dispatch</span><span style="color:#24292E;">} /></span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;"> }</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><p>经过优化后,每次store.state发生变化会触发setState,由React内部的机制来决定组件是否应当重新渲染</p><p>如果组件依赖的state发生变化了,那么React会替我们执行re-render,而不是每次都强制执行re-render</p><p>进一步地,我们可以补充更多细节:</p><ul><li>当组件卸载时解除监听 <ul><li><code>store.subscribe</code>会返回一个<code>unsubscribe</code>函数 用于解除监听</li></ul></li><li>解除与业务代码store的耦合 <ul><li>目前的store来自业务代码 更优的做法是从context中动态获取到store</li><li>应当提供一个context Provider供用户使用</li><li>就像<code>react-redux</code>一样,使用connect前需要将App用Provider包裹并传入store</li></ul></li></ul><p>至此就基本完成了一个connect函数</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group--rLn2" id="tab-9VjmIGc" checked="checked"><label for="tab-9VjmIGc">connect.js</label><input type="radio" name="group--rLn2" id="tab-2z_ZsK9"><label for="tab-2z_ZsK9">storeContext.js</label><input type="radio" name="group--rLn2" id="tab-jSLxG9j"><label for="tab-jSLxG9j">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||||
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><p>经过优化后,每次store.state发生变化会触发setState,由React内部的机制来决定组件是否应当重新渲染</p><p>如果组件依赖的state发生变化了,那么React会替我们执行re-render,而不是每次都强制执行re-render</p><p>进一步地,我们可以补充更多细节:</p><ul><li>当组件卸载时解除监听 <ul><li><code>store.subscribe</code>会返回一个<code>unsubscribe</code>函数 用于解除监听</li></ul></li><li>解除与业务代码store的耦合 <ul><li>目前的store来自业务代码 更优的做法是从context中动态获取到store</li><li>应当提供一个context Provider供用户使用</li><li>就像<code>react-redux</code>一样,使用connect前需要将App用Provider包裹并传入store</li></ul></li></ul><p>至此就基本完成了一个connect函数</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-lr6Qv" id="tab-r-p1wC1" checked="checked"><label for="tab-r-p1wC1">connect.js</label><input type="radio" name="group-lr6Qv" id="tab-Iec5Cbd"><label for="tab-Iec5Cbd">storeContext.js</label><input type="radio" name="group-lr6Qv" id="tab-suI-8zy"><label for="tab-suI-8zy">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// connect.js</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { PureComponent } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'react'</span></span>
|
||||
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { StoreContext } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">'./storeContext'</span></span>
|
||||
<span class="line"></span>
|
@ -1 +1 @@
|
||||
{"article_【字节跳动】前端面试题总结.md":"30e03a5f","article_一文读懂函数中this指向问题.md":"28d5e9b4","article_一文读懂伪类与伪元素.md":"68cce63a","article_【用友金融】前端面试题总结.md":"6d315a97","article_彻底搞懂对象的数据属性描述符、存储属性描述符.md":"dd182e72","index.md":"48a36636","note_ssr.md":"ee0ee312","note_react router.md":"c89e8196","project_clipboardmanager_guide_index.md":"3c3d400d","project_clipboardmanager_statement_index.md":"158b6468","article_深入理解浏览器缓存机制.md":"69e6a2c6","project_clipboardmanager_index.md":"a4052946","project_clipboardmanager_log_index.md":"30d348e4","project_jsrunner_index.md":"d62a7429","article_深入javascript数据类型.md":"477ee358","note_javascript.md":"45a113ba","note_redux.md":"13a0409b","article_深入理解浏览器运行原理.md":"a9684ca4","works_opensource.md":"db24f357","project_markdown_shortcut_index.md":"90359831","article_【快手】深入理解前端面试题.md":"d44b9955","project_markdown_index.md":"5a93c50a","article_深入vue3源码,看看vue.use后究竟发生了什么?.md":"70bae50e","article_一文读懂事件冒泡与事件捕获.md":"d1929e50","note_css.md":"fbe56ac3","article_浅析defineproperty与proxy实现的双向绑定.md":"13ed773f","article_从0实现一个年度报告.md":"175c992f","project_markdown_log_index.md":"bb95b786","note_mysql.md":"45f0f4c7","works_contribution.md":"997cb34f","article_深入理解proxy与reflect.md":"fdad28fc","project_smartwordbreak_index.md":"66a30ca5","project_smartwordbreak_statement_index.md":"33bd8d5d","article_【2023】青训营 - 前端练习题汇总解析.md":"dd1797c0","note_front-end engineering.md":"3049f99d","note_react hooks.md":"5193de15","project_jsrunner_log_index.md":"5b2edea9","self_index.md":"82f653ee","project_smartwordbreak_log_index.md":"6c6fe4e0","note_react.md":"39156ee1","note_javascriptenhanced.md":"f1655783"}
|
||||
{"index.md":"48a36636","article_浅析defineproperty与proxy实现的双向绑定.md":"13ed773f","article_一文读懂事件冒泡与事件捕获.md":"d1929e50","article_深入理解浏览器缓存机制.md":"69e6a2c6","article_一文读懂函数中this指向问题.md":"28d5e9b4","article_深入javascript数据类型.md":"477ee358","note_css.md":"fbe56ac3","article_深入理解浏览器运行原理.md":"a9684ca4","note_redux.md":"02de7bbe","project_smartwordbreak_index.md":"66a30ca5","note_javascript.md":"45a113ba","article_【快手】深入理解前端面试题.md":"d44b9955","article_【字节跳动】前端面试题总结.md":"30e03a5f","article_【用友金融】前端面试题总结.md":"6d315a97","article_深入vue3源码,看看vue.use后究竟发生了什么?.md":"70bae50e","article_一文读懂伪类与伪元素.md":"68cce63a","article_从0实现一个年度报告.md":"175c992f","article_深入理解proxy与reflect.md":"fdad28fc","project_jsrunner_log_index.md":"5b2edea9","note_react router.md":"8d4994d8","project_clipboardmanager_statement_index.md":"158b6468","project_jsrunner_index.md":"d62a7429","project_markdown_index.md":"5a93c50a","article_【2023】青训营 - 前端练习题汇总解析.md":"dd1797c0","project_clipboardmanager_log_index.md":"30d348e4","project_clipboardmanager_index.md":"a4052946","article_彻底搞懂对象的数据属性描述符、存储属性描述符.md":"dd182e72","project_smartwordbreak_log_index.md":"6c6fe4e0","project_smartwordbreak_statement_index.md":"33bd8d5d","note_mysql.md":"45f0f4c7","works_contribution.md":"997cb34f","works_opensource.md":"db24f357","project_markdown_shortcut_index.md":"90359831","project_clipboardmanager_guide_index.md":"3c3d400d","project_markdown_log_index.md":"bb95b786","note_front-end engineering.md":"75c88456","note_ssr.md":"ee0ee312","self_index.md":"82f653ee","note_react hooks.md":"7a05a70a","note_react.md":"f9ad4dc2","note_javascriptenhanced.md":"f1655783"}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user