前言
老外寫技術文章真是叼,這是國外的一個程式設計師寫的一個簡單易懂,循序漸進的Redux教程,本著共享的精神,就翻譯出來給大家一起看,文章最後有連結,不想看我翻譯的直接去看原文吧。
下面是原教程的英文目錄
這篇先更三分之一左右,如果小夥伴們喜歡的話,我再更剩下的,如果沒人看,我沒動力更啊
開始享受你的閱讀之旅吧!本次更新目錄
- 1. 誰適合學習這篇指南
- 2. 你將會學到什麼
- 3. 一個小型的React開發環境
- 4. 什麼是state
- 5. Redux解決了什麼問題
- 6. 為什麼你應該學習Redux
- 7. 你應該使用Redux嗎
- 8. 開始認識Redux的store
- 9. 開始認識Redux的reducers
- 10. 開始認識Redux的actions
正文
當我第一次學習Redux的時候,我希望找到最簡單的教程。
儘管網上有大量的教程,我卻依然無法理解Redux的一些概念
我知道什麼是state, 但是ations, creators, 和reducers又是什麼呢?我對此一頭霧水
最重要的是,我依然不知道怎麼將React和Redux結合起來
這些天,我開始寫我自己的Redux教程,因此,我也學到了很多, 通過寫這個指南,我自學了Redux的基礎,我希望這份教程可以幫助到那些想要學習React和Redux的人
誰適合學習這篇指南
下面的Redux教程正是為這些人準備的:
- 你已經很好地掌握了Javascript, ES6和React
- 你期望用最簡單的方式學會Redux
你將會學到什麼
接下來的指南中你將會學到:
- 什麼是Redux
- 怎樣在React中使用Redux
一個小型的React開發環境
在開始之前,確定你有一個React的開發環境
你可以參照我另外一篇教程如何搭建React, webpack, 和Babel環境, 或者你也可以用create-react-app
腳手架來搭建
什麼是state
為了理解Redux,你必選先理解state
如果你之前使用過React, 那麼你對state這個術語就不會陌生了
比如你之前已經寫過類似於下面的有狀態的React元件:
import React, { Component } from "react";
class ExampleComponent extends Component {
constructor() {
super();
this.state = {
articles: [
{ title: "React Redux Tutorial for Beginners", id: 1 },
{ title: "Redux e React: cos'è Redux e come usarlo con React", id: 2 }
]
};
}
render() {
const { articles } = this.state;
return <ul>{articles.map(el => <li key={el.id}>{el.title}</li>)}</ul>;
}
}
複製程式碼
一個有狀態的React元件是一個javascrit的ES6的類class
每個有狀態的React元件有它自己的狀態
在React元件中,狀態state管理資料,元件可能將資料渲染,顯示給使用者
狀態在響應行為和事件的時候可能會發生變化, 在React中,元件可以通過setState
更新自己的狀態
但是,狀態到底是什麼,這個術語state並沒有繫結在React中,狀態一直在你身邊,即使最簡單的JavaScript應用都有狀態,考慮下面的例子:
使用者點選了一個按鈕
最上層出現了一個彈框
看看,在這個微不足道的互動中就有一個狀態,我們必須處理
我們可以用一個JavaScript 物件來描述初始狀態
var state = {
buttonClicked: 'no',
modalOpen: 'no'
}
複製程式碼
當使用者點選按鈕之後,這個物件就變成了
var state = {
buttonClicked: 'yes',
modalOpen: 'yes'
}
複製程式碼
除了將這些狀態儲存在一個物件中,你如何跟蹤JavaScript的這些狀態?是否有一個庫可以幫我們更可靠地追蹤這些狀態?
Redux解決了什麼問題
一個典型的Javascript應用充滿了狀態, 例如:
- 使用者看到了什麼(data)
- 我們在獲取什麼資料
- 我們展示給使用者的url是什麼
- 在頁面裡面選中了哪些條目
- 應用中是否有錯誤?這個也是狀態
狀態在Javascript中無處不在, 你可以想象一下一個React應用有多少狀態嗎?
當然,只要你的應用一直保持很小,你可以用一個父元件來維持這些狀態,但是當你給你的應用新增更多行為的時候,事情就變得棘手了。
有時候,我們可能希望持續地跟蹤並且獲取到狀態的變化,但是,前端開發者不應該處理這個業務邏輯, 所以還有什麼可選方案來管理React元件的狀態呢?
** Redux**就是其中之一 Redux解決了一個剛開始的時候可能不那麼明顯的難題,它給了每個React元件所需要的狀態
Redux在一個地方維持狀態
當然,使用Redux, 獲取和管理狀態就獨立於React之外了, 這種方式的好處剛開始可能不是那麼明顯,當你越來越瞭解Redux的時候,好處就會變得越來越清晰
接下來,我們來看看你為什麼應該學習Redux以及什麼時候應該在你的應用中使用Redux,首先先來了解為什麼你應該學習Redux
為什麼你應該學習Redux
你是否想學習Redux但是卻不知從何學起,Redux讓大多數開始學習的人望而卻步,但是你不應該被嚇到,Redux並沒有那麼難,關鍵是:不要急著去學Redux,除非你對此有目標和熱情,你才應該開始學習它
彆著急, 我開始學習Redux是因為:
- 我有百分百的興趣瞭解Redux的工作原理
- 我迫切地希望提高我的React技能
- React和Redux結合是十分普遍的
- Redux是通用獨立的框架,一旦學會了,可以到處使用(vue, Angular)
那麼,Redux是一個好的彙報嗎?狀態遍佈在Javascript應用中,所以狀態管理在JavaScript 中一直是個未解決的難題
另一個事實就是:真正的JavaScript應用大多數都是使用狀態管理庫
那麼Redux在未來會消失嗎? 有這種可能,但是這種模式將會長存,它對你前端開發事業極為寶貴
最後,學習Redux或者相關的狀態管理庫是必須的,即使學習曲線很陡峭
你應該使用Redux嗎
使用Redux,Flux或者Mobx來管理狀態完全取決於你
可能你根本不需要這些庫,使用它們的代價就是,他們在你的應用中加了一層抽象
但是我更傾向於認為Redux是一個有用的投資,而不是成本
另外一個開始學習Redux的人常見的問題就是:怎麼知道什麼時候你的應用需要使用Redux?
如果你認為沒有不二法則來確定你什麼時候需要使用Redux來管理狀態, Redux也給JavaScript開發者提供了很多便利, 除錯,action重放等等
當我開始一個React專案的時候,我總是控制不住直接將Redux加入到專案中,但是作為開發者,我們可能就會讓程式碼臃腫了
所以,什麼時候你猜應該將Redux新增到你的專案中?
在挑選Redux之前,先花點時間來探索下可選的模式, 特別是需要深入理解React的state和props
Dave Ceddia有一篇很好的文章children props as an alternative before reaching for Redux,裡面有很多關於用子元件的props來作為Redux代替方案的見解
不要忘記就算之後新增了Redux , React專案也可以很容易地被重構
我總結的你需要考慮使用Redux的情況如下:
- 很多React元件需要獲取同樣的狀態,但是沒有任何父子關係
- 用props一層層往下傳遞狀態給多個元件 讓你棘手了
不用擔心,如果上面的情況對你沒有任何意義,Dan Abramov曾經說過,“Flux就是眼鏡一樣,當你需要他們的時候你會知道的”
在進一步深入之前,你需要花店時間理解Redux解決了什麼問題以及你是否有動力去學習它
注意,Redux對小型應用沒有那麼游泳,在大型應用中它才會大放光彩,無論如何, 即使你當前不是在開發大型應用,學習Redux也不會有壞處
接下來,我們將開始介紹一些概念
- Redux基本原則
- Redux和React結合
再一次重申,確定你搭建好了React的開發環境:你可以跟著 How to set up React, webpack, and Babel這個教程來,或者使用create-react-app腳手架來搭建
開始認識Redux的store
Actions, Reducers,我對這些還是有幾分瞭解的,但是有件事我不明白:這些東西是怎麼聚合在一起的?
在Redux中store精心安排了所有的東西,和我重複一遍:store
store對於Redux來說就像人的大腦一樣:它是某種魔法
Redux的store是根基性的東西,整個應用的狀態存在store之中
轉到你的React開發環境,安裝Redux:
npm i redux --save-dev
複製程式碼
為store建立一個目錄
mkdir -p src/js/store
複製程式碼
在src/js/store
中建立一個新檔案index.js
,初始化store
// src/js/store/index.js
import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;
複製程式碼
從上面的程式碼你可以看出,store是createStore的返回結果,createStore是一個函式,來自redux庫
createStore接受一個reducer作為第一個引數,因此我們傳遞了rootReducer
你也可以傳遞一個初始的state給createStore ,這對服務端渲染有用,但是現在我們不必關心這個
最重要的概念就是redux的state來自於reducers,我們再說的清楚點,reducers產生你應用的狀態
瞭解了這個,我們可以繼續學習我們的第一個Redux reducer了
開始認識Redux的reducers
儘管初始的state對服務端渲染有用,在Redux中,state必須從reducers中返回
那麼什麼是reducer呢?
一個reducer是一個JavaScript函式,一個reducer函式接收兩個引數: 當前的state和一個action(馬上我們會介紹更多關於action的東西)
在一個平常的React元件中,本地的狀態變化是通過setState來改變的, 然而,在Redux中,你不可以這麼做。 Redux的第三個原則是state是不可變的,並且不能改變他們
這就是為什麼reducer必須是純函式,一個純函式是對於一個特定輸入總是會返回同樣輸出的函式
建立一個reducer並不難,它僅僅是一個有兩個引數的JavaScript函式
在我們的示例中,我們將會建立一個簡單的reducer,它接受初始的state作為第一個引數,至於第二個引數,我們提供一個action,現在reducer除了返回初始的state什麼都不會做
為根reducer建立一個目錄
mkdir -p src/js/reducers
複製程式碼
接著在src/js/reducers
裡面建立一個index.js
檔案
// src/js/reducers/index.js
const initialState = {
articles: []
};
function rootReducer(state = initialState, action) {
return state;
};
export default rootReducer;
複製程式碼
我承諾保證這篇指南儘可能地簡單,這就是為什麼我們的第一個reducer很傻了:它返回初始的state,除此之外,就什麼都沒做了
注意初始的state是怎麼作為一個預設引數傳遞的
在接下來的章節中,我們將在裡面新增一個action, 在這裡事情就會變得有趣了
開始認識Redux的actions
毫無疑問,reducers是Redux最重要的概念**,reducers產生應用的狀態**
但是一個reducer是怎麼知道什麼時候產生下一個狀態呢?
Redux的第二個原則就是改變的狀態的唯一方法是傳送訊號給store, 這個訊號就是一個action, 派發action就是一個傳送訊號的過程
現在,你怎麼改變一個不可變的state,你做不到的,新產生的state是當前state新增了新資料後的一個副本,前一個state根本沒發生變化
這就是你需要知道的東西
要明白,Redux的action僅僅是JavaScript物件,下面是一個action
{
type: 'ADD_ARTICLE',
payload: { title: 'React Redux Tutorial', id: 1 }
}
複製程式碼
每個action需要一個type屬性來描述狀態怎樣變化
你也可以申明一個payload,在上面的例子中,payload是一個新文章article,隨後一個reducer將會將這個新文章新增到當前的state
最佳的實踐是在一個函式裡面包裹每個action, 這種函式就叫action creator
現在通過建立一個簡單的Redux 的action,我們可以把所有的東西都整合在一起了
為actions建立一個目錄
mkdir -p src/js/actions
複製程式碼
然後在這個目錄裡面建立index.js檔案
// src/js/actions/index.js
export function addArticle(payload) {
return { type: "ADD_ARTICLE", payload }
};
複製程式碼
type屬性僅僅是一個字串而已
reducer將會使用這個字串來確定怎麼計算出下一個state
由於字串很容易列印出錯和重複,因此將action的type申明為常量更好
這種方式可以避免很難除錯的錯誤
建立一個新目錄
mkdir -p src/js/constants
複製程式碼
然後在這個目錄裡面建立一個action-types.js檔案
// src/js/constants/action-types.js
export const ADD_ARTICLE = "ADD_ARTICLE";
複製程式碼
現在開啟src/js/actions/index.js
, 並且使用action types來更新action
import { ADD_ARTICLE } from "../constants/action-types";
export function addArticle(payload) {
return { type: ADD_ARTICLE, payload };
}
複製程式碼
我們還差一步就可以擁有一個可以執行的Redux應用了,讓我們來重構我們的reducer!
華麗的風格線,哈哈 本篇內容翻譯完畢,溜了,肚子餓的呱呱叫了。