Day18. Redux回顧&邂逅React路由

Redux收尾

  • reducer做一個拆解
  • 拆分到對應(yīng)的文件夾里面, 每個文件夾都有對應(yīng)的4個文件
  • 目錄結(jié)構(gòu)劃分
  • 實際項目會拆解的更細致
  • combineReducers, redux提供的合并函數(shù)
const reducer = combineReducers({
  counterInfo: counterReducer,
  homeInfo: homeReducer
})
內(nèi)部幫助執(zhí)行.png

combineReducer的原理

image.png
  • 看源碼
  • 一點點的去讀


    源碼.png
  • 返回值的本身又是一個函數(shù)
  • 自己寫的reducer函數(shù)有什么缺點? action沒有改變?nèi)魏螖?shù)據(jù), 最終返回的還是原來的state對象, 沒有必要return一個新的對象


    每次都會返回一個新的對象.png
  • combineReduce幫我們做的一個操作, 又發(fā)生改變返回一個新的對象, 沒有發(fā)生改變不返回新的對象


    是否需要返回一個新的對象.png
  • 核心邏輯就是根據(jù)action去獲取下個狀態(tài),然后進行比較

React中的state如何管理

  • 三種方式

    • 方式一: 組件中自己的state管理;
    • 方式二: Context數(shù)據(jù)的共享狀態(tài);
    • 方式三: Redux管理應(yīng)用狀態(tài);
  • 在開發(fā)中如何選擇呢?

    • 沒有一個標準的答案, 官網(wǎng)也說了
    • 某些用戶, 選擇將所有的狀態(tài)放到Reduc中進行管理, 方便追蹤共享;
    • 某些用戶, 選擇將某些組件自己的狀態(tài)放到組件內(nèi)部進行管理;
    • 某些用戶, 將類似于主題、用戶信息等數(shù)據(jù)放到Context中進行共享和管理;
    • 作為一個開發(fā)者, 到底選擇怎樣的狀態(tài)管理方式, 是開發(fā)者的工作之一


      image.png
  • Redux的坐著給出的建議:

    • 在區(qū)分到底如何選擇的時候, 作者判斷狀態(tài)是否需要被多個組件或頁面共享, 并且當路由發(fā)生改變的時候, 頁面銷毀, 有些狀態(tài)可能需要被保存持久化. 對于這種數(shù)據(jù), 作者認為需要被保存到redux中.
      管理建議.png
  • coderwhy的建議:

    • UI相關(guān)的組件內(nèi)部可以維護的狀態(tài), 在組建累不自己來維護; Loading的顯示, isLoad = true; tabbar有三個選項, 用戶點擊操作, currentIndex = 1, 不需要進行共享, 交給組件自己管理


      自己的組件進行維護.png
    • 大部分是需要共享狀態(tài), 都交給redux來管理和維護;(并不是非常絕對的, 父子組件相互傳遞比較方便時自己管理)
    • 從服務(wù)器請求的數(shù)據(jù)(包括請求的操作), 交給redux來維護;
  • 根據(jù)不同的情況會進行適當?shù)恼{(diào)整.

后續(xù)想要補充的東西

  • 結(jié)合實際的項目補充
  • Redux和ImmutableJS結(jié)合使用;
  • 一些性能優(yōu)化的知識;(防止組件動不動就發(fā)生刷新)

Redux回顧

  • 純函數(shù), Redux的Reducer就是一個純函數(shù), (函數(shù)式編程)
  • 為什么要使用Redux
  • Redux核心理念, 三大原則
  • Redux的基本使用, 自己搭建了一個簡單項目
  • Redux里面的目錄結(jié)構(gòu)進行一個拆分, node對ES6模塊化的支持, node已經(jīng)可以升級到12.x的版本了, 建議升級到LTS最新版本
  • Redux流程圖
  • React結(jié)合Redux的使用, redux融入react代碼里面
  • 自定義connect函數(shù), 返回一個高階組件, 公共代碼放到組件類里面, 之后通過map的方式告訴需要哪些事件
  • context如何進行store共享, 原來直接導(dǎo)入store, 不好封裝庫
  • => react-redux官方庫, 直接使用封裝好的Provider
  • 異步操作, 中間件, redux-thunk, dispatch一個action函數(shù)
  • devtools工具
  • redux-saga, 補充generator, saga使用
  • 中間件的原理, Monkey Patching修改dispatch
  • Reducer的拆分, 通過封裝的reducer, combineReducer
  • React中的state到底如何管理的分析
  • thunk用起來容易點用的多, saga可以傳入一個函數(shù)
  • 多練習, 項目中用起來

單向數(shù)據(jù)流

  • 比較廣的一個概念
  • 數(shù)據(jù)的傳遞應(yīng)該是一個單向的, 只能往一個方向傳
  • 三個地方看到過這個概念,
  1. React官方中有提到單向數(shù)據(jù)流, 組件之前數(shù)據(jù)的傳遞, 組件樹, 數(shù)據(jù)在進行共享的時候只能從上往下傳遞, 像水流一樣流到下面. 通過props進行數(shù)據(jù)的傳遞
  2. Vue和React中組件內(nèi)部都有單向數(shù)據(jù)流的概念; 在同一個組件里面, 有UI界面, 產(chǎn)生一個action, 有可能會修改State,


    image.png
  3. Redux中, 一個固定的流程, 組件中發(fā)生事件, dispatch(action), 形成一個閉環(huán), 整個過程中不能越級


    不能越級.png

TransitionGroup的警告問題

  • 在group的里面, button, in去除不需要加上去


    image.png

    消除警告.png

React-router的使用

路由的由來

  • 映射關(guān)系, 路由表


    i路由的由來.png
  • 編程里面路由的概念, 最早是后端里面, 前后端分離, 單頁面富應(yīng)用(SPA), 編程和建筑學

階段一: 后端路由(渲染)階段

  • 早期的網(wǎng)站開發(fā)整個HTML頁面是由服務(wù)器來渲染的.
    • 服務(wù)器直接生產(chǎn)渲染好對應(yīng)的HTML頁面, 后面給客戶端進行展示. (SEO優(yōu)化, 爬蟲靜態(tài)頁面, ssr(服務(wù)端渲染), 谷歌執(zhí)行JavaScript代碼幫助發(fā)送Ajax請求, 搜索結(jié)果)
  • 但是, 一個網(wǎng)站, 這么多頁面服務(wù)器如何處理呢?
    • 一個頁面有自己對應(yīng)的網(wǎng)址, 也就是URL.
    • URL會發(fā)送到服務(wù)器, 服務(wù)器會通過正則對該URL進行匹配, 并且最后交給一個Controller進行處理.
    • Controller進行各種處理, 最終生成HTML或者數(shù)據(jù), 返回給前端.
    • 這就完成了一個IO操作.
  • 服務(wù)端完成頁面的渲染, 服務(wù)器端渲染(SSR) server side render.


    后端路由, 服務(wù)端渲染.png

    后端路由.png
  • 前后端分離, 解耦

階段二: 前后端分離階段

  • 前端渲染的理解:
    • 每次請求涉及到的靜態(tài)資源都會從靜態(tài)資源服務(wù)器獲取;
    • 這些資源包括HTML+CSS+JS, 然后在前端對這些請求回來的資源進行渲染;
    • 需要注意的是, 客戶端的每一次請求, 都會從靜態(tài)資源服務(wù)器請求文件;
    • 同時可以看到, 和之前的后端路由不同, 這時后端只是負責提供API了;
  • restful接口規(guī)范, 后端提供接口文檔, 不需要關(guān)注前端實現(xiàn)
  • 這樣后端不僅能給web端提供數(shù)據(jù), 還能給iOS、安卓、PC提供支持


    image.png

階段三: 單頁面富應(yīng)用(SPA)

  • 單頁面富應(yīng)用的理解:
    • 單頁面富應(yīng)用的英文是single-page application, 簡稱SPA;
    • 整個Web應(yīng)用實際上只有一個頁面, 當URL發(fā)生改變時, 并不會從服務(wù)器請求新的靜態(tài)資源;
    • 而是通過JavaScript監(jiān)聽URL的改變, 并且根據(jù)URL的不同區(qū)渲染新的頁面;


      image.png
單頁面富應(yīng)用.png

-目前比較多的是處于第三個階段, 單頁面富應(yīng)用

前端路由的原理

前端路由的核心:

  1. 改變URL, 但使頁面不要進行強制刷新(a元素不行)
  2. 自己來監(jiān)聽URL的改變, 并且改變之后自己改變頁面的內(nèi)容
  • URL后面跟上一個哈希值, 頁面不會發(fā)生刷新, URL的哈希, 有一個缺點, 中間莫名多了一個#
  • HTML5中的history模式修改URL
  • 當監(jiān)聽到URL發(fā)生改變的時候, 自己決定顯示什么內(nèi)容

URL的hash

  • URL的hash
    • URL的hash也就是錨點(#), 本質(zhì)上是改變window.location的href屬性;
    • 我們可以通過直接賦值location.href
window.addEventLIstener("hashchange", () => {
  switch (location.hash) {
    case: "#/home":
      routerViewEl.innerHTML = "首頁";
      break;
    case "#/about":
      routerViewEl.innerHTML = "關(guān)于";
      break;
    default:
      routertViewEl.innerHTML = "";
  }
})
image.png

HTML5的history

  • history接口是HTML5新增的, 他有六種模式改變URL而不刷新頁面


    image.png
// 1. 獲取reouter-view的DOM
const routerViewEl = document.getElementsByClassName("router-view")[0];

// 獲取所有的a元素, 自己來監(jiān)聽a元素的改變
const aEls = document.getElementsByTagName("a");
for (let el of aEls) {
  el.addEventListener("click", e => {
    e.preventDefault();
    const href = el.getAttribute("href");
    console.log("a元素發(fā)生了點擊");
    history.pushState({}, "", href);
  })
 }

// 執(zhí)行返回操作時, 依然來到urlChange
window.addEventListener("popState", urlChange);
// window.addEventListener("go", urlChange);// 手動執(zhí)行g(shù)o時監(jiān)聽

// 監(jiān)聽URL的改變
function urlChange() {
   switch (location.pathname) {
    case: "/home":
      routerViewEl.innerHTML = "首頁";
      break;
    case "/about":
      routerViewEl.innerHTML = "關(guān)于";
      break;
    default:
      routertViewEl.innerHTML = "";
  }
}
image.png

react-router

  • 目前前端流行的三大框架, 都有自己的路由實現(xiàn):
    • Angular的ngRouter
    • React的react-router
    • Vue的vue-router
  • React Router的版本4開始, 路由不再集中在一個包中進行管理了:
    • react-router是router的核心部分代碼;
    • react-router-dom是用于瀏覽器的;
    • react-router-native是用于原生應(yīng)用的;
  • 目前我們使用React Router最新的版本是v5的版本:
    • 實際上v4的版本和v5的版本差異不大;(寫錯了一個版本依賴, 直接升級了)
  • 安裝react-router:
    • 安裝dom會自動幫助我們安裝react-router的依賴 yarn add react-router-dom

Router的基本使用

  • react-router最主要的API是給我們提供的一些組件:
    • BrowserRouter或HashRouter:
    • Link和NavLink:
    • Route:


      image.png
<HashRouter>
  <Link to="/" >首頁</Link>
  <Link to="/about" >關(guān)于</Link>
  <Link to="/profile" >我的</Link>

  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/profile" component={Profile} />
</HashRouter>

coderwhy的React核心技術(shù)與開發(fā)實戰(zhàn)課程鏈接

少年~來做同學呀~.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容