Redux 的前世今生

本篇文章主要內容是介紹 Redux 的歷史背景、實戰和概念,目標讀者設定為 redux 初級玩家。

既然定位為初級玩家,那么就不會講源碼、實現、設計原則這些東西。我會帶你站在歷史的角度俯覽 redux 的傳奇一生,并通過代碼示例掌握基本用法,通過圖示把道理捋明白。

Redux 是什么?

redux 官方自述是 A Predictable State Container for JS Apps,通俗理解,是一個用于 JavaScript 的狀態管理庫。注意:它特別強調了 Predictable State(可預測狀態)。

什么是狀態?

這個很好理解,萬物皆有狀態,可以把人類簡單的分成清醒/睡眠/昏迷等狀態。還可以繼續細化,比如情緒,分為生氣/冷靜/憤怒/開心等狀態。身體的某個部位,比如眼睛,失明/睜開/閉眼等狀態。

為了更加容易理解狀態,這里拿最典型的 TodoList 舉例。

最原始的 web 應用,在沒有狀態的情況下,應該怎么做呢?

<!-- todolist 原始版 -->
<div id="todo-list">
  <div>
    學英語<span> 未完成 </span><button onclick="complete(this)">完成</button>
  </div>
  <div>
    學數學<span> 已完成 </span><button onclick="complete(this, true)">取消完成</button>
  </div>
  <div>
    學語文<span> 未完成 </span><button onclick="complete(this)">完成</button>
  </div>
</div>
<script>
  function complete(target, cancel = false) {
    if (cancel) {
      target.textContent = "完成";
      target.onclick = () => complete(target);
      target.previousElementSibling.textContent = " 未完成 ";
    } else {
      target.textContent = "取消完成";
      target.onclick = () => complete(target, true);
      target.previousElementSibling.textContent = " 已完成 ";
    }
  }
</script>
復制代碼

可以看到,代碼比較簡單,這種代碼在四五年前是非常流行的,但是現在已經很少有人這么寫代碼了。

如果加入狀態的概念,應該怎么做?

<!-- todolist 狀態版 -->
<div id="todo-list"/>
<script>
  var todoEl = document.getElementById("todo-list");
  var state = {
    todoList: [
      { id: 1, name: "學英語", complete: false },
      { id: 2, name: "學數學", complete: true },
      { id: 3, name: "學語文", complete: false }
    ]
  };
  function render() {
    const todoHtml = state.todoList
      .map(
        item =>
          `<div>${item.name} ${
            item.complete
              ? `已完成 <button onclick="complete(${item.id}, true)">取消完成</button>`
              : `未完成 <button onclick="complete(${item.id})">完成</button>`
          }</div>`
      )
      .join("");
    todoEl.innerHTML = todoHtml;
  }
  function complete(id, cancel = false) {
    state.todoList.find(item => item.id === id).complete = !cancel;
    render();
  }
  render();
</script>
復制代碼

可以看到,比起原始版實現,狀態版的代碼好像更多。

有狀態和無狀態應用的區別

兩份代碼的顯示效果是完全一致的注册送28体验金的游戏平台,那么,到底哪個版本更好呢?

如果功能確定下來,只有目前的這么點功能,并且不會有任何需求的變動,那么無疑,第一種實現是更優選擇。但這種情況還是在少數,更多情況下,應用總是會存在各種不確定性,隨時都可能變動。

以前的 web 應用,不能稱之為應用,只能叫網頁,大一點的叫網站。現在為什么叫 web 應用了?因為這么叫高大上嗎?并不是,而是現在的 web 應用更大,更復雜了。

你可以仔細觀察,原始版 button 的文字和 click 綁定的函數,與前面的“學數學”、“學英語”完全無關。如果要給頁面添加新的元素,比如什么時候完成的,點擊每一條 item 會彈出詳情等。這樣擴展下去,應用會越來越混亂和復雜。

狀態版的實現,比原始版多了一個state變量和一個render函數。

其中,state就是應用的狀態,當頁面發生操作時,修改state。當應用的state發生變化時,就會調用render方法,重新渲染頁面。

這就是有狀態和無狀態的區別。

是不是有點 react 和 vue 的味道了?

react 和 vue 都有staterender。react 的state,vue 的data,都是可以響應數據變化而自動重繪頁面的。只不過實現方式不同。react 是在this.setState后發生重繪,vue 是通過對對象和數組進行數據劫持實現的,但它們同時也帶來了新的問題,比如 react 中異步的渲染,vue 在data聲明后新添加的屬性無法自動響應等。更為細節的部分不多說,不在該文章范圍以內。

為何需要狀態管理容器?

現在已經明白了狀態的作用,那么,既然 react 和 vue 自身都有狀態系統,為什么還需要狀態管理庫呢?

原因是因為在組件化的探索中出現了問題。

一個正常的組件樹像下面這張圖。

使用組件化的應用,可能存在幾百上千個組件,如果不使用狀態管理庫,狀態會散落在每個組件內部。一些需要共享的狀態,可能要傳給父組件,祖輩組件,也可能要傳給子組件、子孫組件,還可能要傳給兄弟組件,祖輩的兄弟組件等等。這些場景雖然仍能通過 props 的機制完成,但是非常不直觀,會讓人感到錯綜復雜,這好像又找到了以直接修改 DOM 的方式來編寫代碼的感覺,這很危險。

為此,react 沒有提供什么特殊的方案,它建議直接使用 flux 模式來解決。而 vue 沒有放棄,它提供了很多種解決方案,v-modelsync$attrs$listeners等等,但沒有什么實質性的改變。

跨組件通信,是一個必須要解決的問題。

真正有實質性變化的,是 react 的 context API 和 vue 的 vue event bus 模式。

它們很像,又有所區別。它們存在同樣的問題,改變狀態的過程不夠直觀,雖然可以跨組件修改某個狀態,但很難對這個操作進行跟蹤、定位和預測。

這樣雖然給我們極大的自由任意操作全局狀態,但讓我們難以快速找到究竟是誰在什么時候改變了某個全局狀態。

所以,還需要更加規范細致的解決方案,可以追蹤數據何時變化的狀態管理庫,即本節開頭所講的可預測狀態,這也是 redux 一再強調的特性。

解決問題的路上總是會出現更多新的問題,這個過程就像是俄羅斯套娃,一步步無限接近真理,可世界上根本沒有真理。

Redux 的歷史

redux 在 github 上的第一次提交記錄是 2015 年的 5 月 31 日,提交者是 gaearon,名字翻譯過來你可能非常熟悉,叫蓋倫。這個蓋倫就是大名鼎鼎的 Facebook 工程師 Dan Abramov,國內俗稱 Dan 大神。dan 大神是一個非常真實的人,不掩飾問題,不故作高深。很多人都非常喜歡他,這里是他的。

redux 并不是憑空出現的,在它之前,facebook 還有一個叫做 flux 的庫,flux 是 2014 年 7 月 24 日開源的。對于現在的前端開發者來講,flux 可能比較陌生。因為在它那個時代,前端領域還沒有特別重視應用的狀態,所以 flux 在當時并不流行。2014 年是什么時代?要知道現在所謂的前端三大框架資歷最老的 Angular 出現的時間也才是 2014 年 9 月 19 日,比 flux 還要晚出現 2 個月。那個時代,還是 jQuery 和 Bootstarp 橫行的時代。flux 在最開始的一段時間里,很多人不解和困惑,甚至有人提出 flux 是事件編程的倒退。其實當時很多人沒有正確地看到 flux 想做什么,只是停留在表面的 API 的用法上,沒體會到 flux 真正的核心是一個單向數據流的狀態機。經過一段時間注册送28体验金的游戏平台,flux 逐漸被人理解和認可。不巧的是之后不到一年的時間里,mobx 和 redux 相繼出現,它們都在 flux 的基礎上做了大量改進,所以它們比 flux 更加優秀。flux 沒有機會大放異彩就被埋沒在了歷史的長河中,屬于一個曇花一現的庫。現在出現最頻繁的地方,大概就是類似我這篇文章一樣介紹 redux 歷史的文章或書中。

所以,前端的應用狀態這一概念在業界成型的時間大概是 2013 年到 2014 年左右。

Redux 難嗎?它好學嗎?學習路線是什么?

如果以一個過來人的身份回答,redux 很簡單,它不難。

畢竟它的 js 源碼僅有 712 行,包括注釋和換行符,如果愿意認真讀的話,半天時間就能讀完一遍。

可是如果把時間回放到幾年前我剛開始接觸 redux 的時候,我也是很懵的。

現在讓我以一個初學者的身份來回答這個問題的話,應該是這樣,redux 本身非常簡單,但學習它有些難度。

昨天看阮一峰老師最新寫的《科技愛好者周刊:第 99 期》中說了這么一件事。

兩天前,ZDNet 發表了新文章《認識 iPad:提高你生產力的 10 個應用》。這一類的科普文章,每周都會出現,這難道不是一件很奇怪的事情嗎?

iPad 已經發布 10 年了,可是人們還必須看這種文章,說明大家還沒找到辦法,到底怎樣才能在 iPad 上進行實際工作!

這讓我想到了現在的 redux。其實到現在,還是有很多人在寫關于 redux 的文章,也有很多人在問關于 redux 的疑惑。這說明大家需要 redux,但至今仍未找到學習 redux 的方式。所以我嘗試把我這幾年使用 Redux 的心得體會寫一寫,或許會對大家有所幫助。

dan 大神在 redux 發布 3 年后的某一天,提交了一條。

標題是“Remove "Redux itself is very simple"”,意思是刪除了一段文字,“Redux 本身非常簡單”。

同時,dan 大神還在該條 commit 中提到:

Reflecting a few years later this was a bit of a silly thing to write in the docs. Of course it's not simple to people learning it.

翻譯成中文的意思是:

幾年后,仍在文檔中強調“react 本身非常簡單”是一件很愚蠢的事情。 當然,要學習它并不容易。

由此可見,Redux 對新手而言確實不怎么友好。

至于怎么學習,推薦三條路。

第一條,英語好的同學,去看,這是最佳學習方法。也可以看一些優秀的資源。比如、、等。

第二條,技術非常強的同學,大體翻閱下文檔,寫兩個 demo,然后去讀源碼吧。

第三條,技術一般,英語也挺差的同學。看一些中文資料也不錯,比如現在你正在看的這篇文章。

學習這件事,盡量還是要去源頭看看。“取乎其上,得乎其中。取之于中,而求之于下。“。

但也不用過度強求,總之學會才是目的,具體怎么學,還是要看你習慣哪種方式。

Redux 解決了什么問題?

redux 和類似的框架都在解決 web 應用中狀態難以管理的問題。

facebook 面臨的問題

在早期,facebook 的 web 網站經常會碰到數據和視圖不一致的現象。比如消息圖標莫名其妙的亮起,當點擊圖標后,又發現沒有消息。facebook 的工程師們不止一次地解決這個 BUG,但每次修復后的一段段時間里都會重復出現。

造成這個現象的原因是數據和視圖的復雜關系。數據的流向很難預測,所以也很難理清它們之間具體的關系是怎樣的。

借用一張網圖來看一下 jQuery 時代的應用數據流向。

這非常糟糕。

狀態管理庫的鼻祖 flux

facebook 的工程師在探索這個問題時,給出的第一個答案就是 flux。

flux 不僅僅是一種庫或框架,更是一種模式或架構。這種模式或架構的名字也叫作單向數據流。

flux 非常好理解。

比如頁面初始化加載的這個動作,是一個 Action, dispatcher 會把 action 傳遞給 store,dispatcher 會修改應用的 store,store 的改變會重繪視圖 view。一個界面就加載出來了,非常簡單的原理。

視圖 view 上有一個按鈕,點擊按鈕的動作,又是一個 Action注册送28体验金的游戏平台, action 又會告訴 dispatcher 該去通知 store 了,然后 store 會發生改變,重繪 view。如此循環往復,越來越簡單了。

從上面兩張圖中可以看出,無論應用程序多么復雜,數據變化的流向總是一致的。

如果再加上 api 的調用,流程是這樣的。

注意:這是 flux 的數據流向圖,redux 和它有所區別。但不用在意,這里只是大概演示下流程。

事實證明,flux 是對的。

在之后的探索中,facebook 又做出了更讓人滿意的答案,redux 和 mobx。尤其是 redux。

雖然 flux 和 react 在設計原則和思想的細節上有較大的差異,但解決的問題是相同的。

react 解決的問題就是通過單向數據流的架構方式使應用的狀態按照一定的模式來變化,從而能夠預測應用的狀態。

Redux 和 React-Reudx 的關系

Redux 本身是完全獨立運行的庫,不會基于某個庫或框架、也不會依附于某個庫或框架。所以,react 雖然可以直接使用 redux,但是無法和自身的響應式結合。

為了解決這一問題,facebook 又開發了 react-redux。

兩者是有區別的,redux 的責任是單純的狀態管理,react-redux 更像一個膠水,把 react 應用程序和 redux 狀態倉庫粘在一起。讓 redux 中數據的變化可以觸發 react 中的數據響應視圖。

下面這段話是來自于 redux 官網:

Keep in mind that Redux is only concerned with managing the state. In a real app, you'll also want to use UI bindings like .

翻譯成中文意思是:

請記住,Redux 僅與管理狀態有關。在真正的應用程序中,您還需要使用 UI 綁定的庫,例如。

很多人在學習和理解 redux 時,經常會出現概念混淆的問題,我覺得這是學習 redux 的一大屏障。事實上,概念越多的庫或框架,越難學習,比如 rx.js。

Redux 的用法

我認為先學習用法,再去理解概念相對更友好一些。因為這樣更加直觀。

Redux 在原生 js 中的簡單使用

我一直在強調 redux 是可以獨立運行的,從某種程度上,redux 和 react 沒有任何瓜葛,記住這一點,這很重要。

下面用代碼演示如何在原生 js 中使用 redux,仍然是那個 todolist 示例,拿之前寫的狀態版進行重構。

<!-- todolist redux版 -->
<script src="https://unpkg.com/redux@4.0.5/dist/redux.js"/>
<div id="todo-list"/>
<script>
  let todoEl = document.getElementById("todo-list");
  // 1. 定義 action types,它描述了你的應用程序有幾種改變數據的操作
  let COMPLETE = "COMPLETE";
  let CANCEL_COMPLETE = "CANCEL_COMPLETE";
  // 2. 定義 reducers
  // reducer 默認會有 2 個參數,第一個是初始狀態,第 2 個是 dispatch 傳遞進來的 action
  let initialState = [
    { _id: 1, name: "學英語", complete: false },
    { _id: 2, name: "學數學", complete: true },
    { _id: 3, name: "學語文", complete: false }
  ];
  function todoReducer(state = initialState, action) {
    // 通過判斷 action 的 type 屬性,來進行不同的 state 變化。
    switch (action.type) {
      case COMPLETE:
        state.find(item => (item.id = action.id)).complete = true;
        return state;
      case CANCEL_COMPLETE:
        state.find(item => (item.id = action.id)).complete = false;
      default:
        return state;
    }
  }
  // 3. 調用 createStore 創建 store,todoReducer 是必傳參數
  let store = Redux.createStore(todoReducer);
  // 4. 定義 actions creator,它們是一個函數,返回一個簡單對象
  let completeAction = id => ({
    type: COMPLETE,
    id
  });
  let cancelCompleteAction = id => ({
    type: CANCEL_COMPLETE,
    id
  });
  function render() {
    // 5. 使用狀態時,調用 store 的 getState 方法可以獲取最新的狀態
    const todoHtml = store
      .getState()
      .map(
        item =>
          `<div>${item.name} ${
            item.complete
              ? `已完成 <button onclick="complete(${item._id}, true)">取消完成</button>`
              : `未完成 <button onclick="complete(${item._id})">完成</button>`
          }</div>`
      )
      .join("");
    todoEl.innerHTML = todoHtml;
  }
  function complete(id, cancel = false) {
    // 6. complete 函數不再直接修改 state 中的數據,而是調用 store 對象的 dispatch 方法傳遞 action 的方式來創建新的 state
    store.dispatch(cancel ? cancelCompleteAction(id) : completeAction(id));
    // render(); 不再這里重繪,而是使用 store 的 subscribe
  }
  // 7. 使用 store 的 subscribe 監聽 state 的變化,它的參數是一個回調函數,每次 state 變化,都會自動調用該函數
  store.subscribe(render);
  render();
</script>
復制代碼

代碼中有詳盡的注釋,這幾乎是一個 redux 應用的最簡版本。看明白這個例子,就搞懂了 redux 最基本的使用。

雖然代碼的注釋中標注了各個步驟的序號,但你可以不按照這個順序來寫代碼。標注只是為了方便理解。

Redux 中各個 API 和概念之間的關系

現在來回顧一下,上面的代碼都做了什么。

首先要有一個 store,創建 store 需要調用 Redux.createStore()。 createStore 接受一個 reducer 函數作為參數。reducer 默認有 2 個參數,第 1 個是 state,它是當前狀態樹,第 2 個是 action,這個參數其實就是 store 對象的 dispatch 方法傳遞的參數 action。

action 是一個結構簡單的對象,它有一個 type 屬性,用于標記這個 action 是做什么的,與之對應的 reducer 函數會通過 switch 來處理這個 action。

創建 action 對象的函數叫做 action creator,它也非常簡單,就是返回一個 action 對象。

reducer 函數是處理數據變更的地方,它會返回一個新的對象,這個對象就是新的狀態。這和 Array 的 reduce 的運行機制非常相像。

store 的 getState 方法用于獲取當前狀態樹對象 state;subscribe 方法用于監聽 state 的變化,它接受一個函數作為參數,每次數據發生變化時,調用改回調函數。

很多人在剛開始學習 redux 時,被各個概念和它們之間的關系弄的云里霧里,我認為只要把這些概念之間的關系梳理清楚,學習 redux 的一大門檻就算跨過去了,為此我特意畫了一張簡單的關系圖。

如果你從來沒有使用過 redux,那你一定會覺得這里面的各種參數傳來傳去,函數調來調去,就像變戲法一樣。為什么不直接修改 state 呢?state 的本質不就是一個全局對象嗎?

確實是這樣,state 就是一個全局對象。

如果直接修改 state 會有幾個問題。

  1. 你可能并不知道在哪里修改的對象。

當一個數據沒達到預期時,很難找到到底是在哪里修改了這個數據。

  1. 你可能在兩星期后已經忘記為什么要在某個地方修改 state。

雖然你可以使用注釋來在一定程度上解決這個問題。

  1. 這樣做非常不安全。

JavaScript 的對象是非常松散的,你可以隨意修改,也可以把它弄丟。比如在某個不起眼的角落,寫了一行 state = null;

處理數據最規范的手段就是通過某種模式來變更它們,而不是直接用=來修改。最典型的例子是數據庫。

在 2017 年 8 月份,有一篇文章曾經非常火爆,。像數據庫一樣設計你的 Redux,你可以讀一下。

redux 是一個 JavaScript 數據容器,其實它更像一個數據庫。

而我們所做的一切和 redux 中那些看似繁瑣的 API 都是為了讓數據的更新是可預測可追蹤的,如果使用 redux 的方式來處理數據,你可以馬上找到這次狀態變更是因為什么,是在哪個地方讓數據發生了變化。這是 redux 的唯一好處。

再來思考一個問題,一個簡單的 todoList 應用把代碼弄的這么復雜,有必要嗎?

事實上,無論如何都找不到任何必須使用 redux 的理由。

redux 帶給我們的不僅僅是學習成本,還會讓我們多寫很多代碼。

這是付出,同時還要看收益。正常情況下,收益要高于付出,至少也要持平,我們才會考慮付出。沒有人會傻到自己給自己刨坑吧?

很多初學者在學一門框架或庫時就想把全家桶全用上,這是絕對不可取的。

redux 的開發動機在官網上寫的很明白,就一句話:our code must manage more state than ever before.(我們的代碼變必須管理比以往更多的狀態)

換句話說,我們的應用中存在大量狀態時,才應該考慮使用 redux,而不是在一開始就優先考慮使用 redux。

上面的例子使用了大部分 redux 的核心 API,但沒介紹combineReducersapplyMiddlewarebindActionCreatorscompose這幾個更高級的 API,因為它們都不是最核心的 API,而是為了解決某項更高級的問題而存在的。這些不會在這里講,但會在下一篇文章中提到。

dan 大神在 2018 年曾經發表過一篇文章,(你可能不需要 redux),你可以讀一讀。然后認真思考,到底需不需要 redux。我所指的不是到底需不需要學習 redux,而是在你的應用程序中需不需要使用 redux。redux 是一個優秀的庫,作為前端工程師,無論怎樣總是要見識一下的。

Redux 在 React 中的使用

雖然 redux 可以在任何環境下使用,但 facebook 開發它的最初目的還是為了解決大型 react 應用的狀態管理問題。

在 react 中使用 redux,一般都會用到 react-redux 這個庫。文章前面有提到,react-redux 本身就像是一個膠水,并不復雜。

Provider 和 connect

它的用法大概是這樣。

首先導出一個叫做 Provider 的組件,然后在 Provider 組件中注入 store。再用 Provider 把應用的根組件包裹起來。這樣就可以使用 store 了。

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./store";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store="{store}">
    <App/>
  </Provider>,
  rootElement
);
復制代碼

react-redux 是基于 react 中的 context 來實現的,所以這一步是必須的。

需要使用 store state 的組件,使用 connect 函數將 store 和 react 的組件連接起來。

import { connect } from "react-redux";
import { increment, decrement, reset } from "./actionCreators";
const Counter = props => <div> {props.counter} </div>;
const mapStateToProps = (state ) => {
  return {
    counter: state.counter
  };
};
const mapDispatchToProps = { increment, decrement, reset };
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
復制代碼

如果不需要 store 的組件,在寫法遵循 react 的正常寫法即可,不需要變動。

代碼中多了兩個新的概念,mapStateToProps 和 mapDispatchToPorps,其實它們非常好理解。

mapStateToProps 是將 redux 中 state 映射到 react 組件的 props 中,其實就是 getState 的作用。

mapDispatchToProps 是將 redux 中的 dispatch 映射到 react 組件的 props 中,這樣就可以使用props.increment來調用 dispatch。

react-redux 的原理就是將數據提升至最高組件,然后在組件中通過 props 層層傳遞。

react-redux 的使用就這么簡單,是的,非常簡單。

hooks

什么是 hooks?

hooks 是 react 16.8 推出的新特性,一個替換 component 組件的方案,react 未來的發展方向。

在 hooks 出現之后,我們不再需要 connect。

react-redux 最常用的 hooks 有 3 個,useSelector、useDispatch 和 useStore。

useSelector 取代的是 mapStateToProps,useDispatch 取代的是 mapDispatchToProps。useStore 是對 store 的引用。

同樣是上面那段計數器代碼,用 hooks 會這樣寫。

import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement, reset } from './actionCreators'
export default const Counter = () => {
  const counter = useSelector(state=>state.counter);
  const dispatch = useDispatch();
  // 如果你要調用 dispatch
  // dispatch(increment());
  return (
        <div> {counter} </div>
    )
}
復制代碼

可以看到,使用 hooks 后,代碼變得非常優雅。

hooks 已經出現 3 年,現在非常穩定,如果還認為 hooks 是新特性,那真是有點跟不上時代的節奏了。我非常推薦使用 hooks,現在我開發的 react 項目中幾乎全部都是函數式組件和 hooks。

需要注意的是,hooks 不能在 class 組件中使用,它只能在函數組件中使用,而且只能在函數的最外層中使用,這些都取決于 hooks 的實現方式。

寫在最后

通過這篇文章的學習,你應該已經掌握了 react 最基本的使用,如果文中所講述的東西你都能夠掌握并理解,那么恭喜你,已經成為一個合格的 redux 初級玩家了!

不過,游戲才剛剛開始。

接下來我會再寫兩篇關于 Redux 的文章,讀者群體定位分別是中級玩家和高級玩家,敬請期待。

原文鏈接:

上一篇:數據結構總結(四)二叉樹
下一篇:🔥手寫大廠前端知識點源碼系列(上)

相關推薦

  • (轉載)如何通俗易懂的理解Redux

    作者:Wang Namelos 鏈接:https://www.zhihu.com/questio...(https://www.zhihu.com/question/41312576/answer/9...

    2 年前
  • 面試還問redux?那我從頭手擼源碼吧(中間件篇)

    昨天的文章手寫了一版redux的核心源碼(https://segmentfault.com/a/1190000016799698),redux庫除了數據的狀態管理還有一塊重要的內容那就是中間件,今天我...

    1 年前
  • 閱讀redux源碼_compose

    先上源碼: 重點看一句就夠了: 現在我們先假設一個數組,有3個函數,分別是x,y,z 那么發生什么了,接下來就一步一步解釋 1. 變成reduce模式: 2. reduce第一次執行,...

    2 年前
  • 跟著例子一步步學習redux+react-redux

    前言 本文不會拿redux、reactredux等一些react的名詞去講解,然后把各自用法舉例說明,這樣其實對一些react新手或者不太熟悉redux模式的開發人員不夠友好,他們并不知道這樣使用...

    2 年前
  • 超級易懂的redux-saga原理解析

    原文地址(https://github.com/zyl1314/blog/issues/14) 前言 筆者最近在做一些后臺項目,使用的是Ant Design Pro(https://github...

    1 年前
  • 讀redux源碼總結

    redux介紹 redux給我們暴露了這幾個方法 我們來依次介紹下 createStore 源碼 個人覺得compose(a,b,c)(d)后的代碼就是a(b(c(d))),co...

    2 年前
  • 詳解redux異步操作示例

    一、redux基礎 (https://img.javascriptcn.com/3c838d74abd0220ea77efc3756edb0cd) redux 通過 dispatch(a...

    1 年前
  • 詳解react、redux、react-redux之間的關系

    本文介紹了react、redux、reactredux之間的關系,分享給大家,也給自己留個筆記,具體如下: React 一些小型項目,只使用 React 完全夠用了,數據管理使用props、sta...

    1 年前
  • 記錄一篇redux-saga的基本使用過程

    安裝 配置action actionType 創建文件,在文件中添加需要的action類型 createActions 創建文件,在文件中編寫action 配置red...

    2 年前
  • 解密Redux: 從源碼開始

    是當今比較流行的狀態管理庫,它不依賴于任何的框架,并且配合著的使用,在很多公司的React項目中起到了舉足輕重的作用。接下來筆者就從源碼中探尋Redux是如何實現的。

    8 個月前

官方社區

掃碼加入 JavaScript 社區