淺析 React Redux 的概念以及使用
前言
學習 react 的過程中,就一直看到什麼 redux,後來稍微了解一點點之後,如果你跟我一樣有一點點使用過 vue 的經驗的話,我自己感覺和 vuex 的作用有點類似,所以個人認為是必須要學會的東西。然而發現 redux 其實是一塊有點難咬的骨頭,不是那麼隨隨便便看看文檔,百度一下就可以學會的東西,所以同樣的,希望通過寫篇博客的方式,學習好關於 redux 的基本知識點。
正文
在真正進入 redux 前,我想先引出,或是說先說說為什麼我們需要 redux,他又幫我們做了什麼?
為什麼需要 Redux?
先說,react 本身是一個非常輕量級的框架,其實根本不一定要用到 redux,在不需要使用 redux 的情況下硬要用只是增加應用的複雜度而已。
好的,試想如果今天要寫一個稍微複雜一點點的應用,肯定會有不少組件。那麼這些組件之間肯定會有一些數據要共享,像下圖情況,假設我們把組件的關係抽象成如下樹形結構,如果有一個上層組件需要用到下層組件的數據,那只用 react 寫會變得很麻煩很混亂,因為組件之間的關係導致傳值(props)太麻煩了。
這時候就是 redux 上場的時候了。我們可以通過 redux 幫我們將需要在多個組件之間共享的數據抽取出來到一個公共的 store 數據層,這樣所有需要對這些數據訪問的組件都只要和 store 打交道就好。
這主要就是 redux 最強大的地方,關於 redux 其實是 flux 的一個實現,關於 flux 之後有機會會再寫篇博客。那大概知道 redux 在幹嘛了之後,接下來我們就來進入 redux 的世界吧!
Redux 準備
要使用 redux 首先當然先安裝點東西啦~
// npm
npm install redux
npm install react-redux
// yarn
yarn add redux
yarn add react-redux
下面的會簡單用 redux 開發一個 counter 計數器應用,會通過 create-react-app 所建立的 react 項目進行介紹,如果還不會使用 create-react-app 的人歡迎先去看看 React 教程之使用 create-react-app 构建你的第一个 react 应用。
Redux 工作流程
下圖是官方文檔對 redux 的圖示:
簡單來說,redux 就是一個數據層的框架,它把所有數據都存在 store 中,store 就是一個公共存儲數據的區域,組件可以從 store 中拿數據,也可以對 store 中的數據進行修改。
我們把 redux 整個流程比喻成圖書館的流程,個人覺得有助於理解:
React component
就是要借書的人,action creators
就是當我要借書時,會跟圖書館管理員說我要借什麼書,比如說『我要借 type 為 科幻類 name 為 哈利波特的書』,那麼這個語句的表達(也就是說這句話),就是所謂的 action
。
Store
就是圖書館管理員,他負責他負責整個圖書館所有書的管理。Reducer
則相當於是一個記錄本,因為圖書館管理員是沒辦法記住所有存書情況的,就需要這麼一個記錄本,來查一下你要借的書有沒有,在哪裡之類的。
轉換成代碼理解如下:
- 獲取數據
組件要去獲取 Store 裏的數據,跟 Store 說我要獲取數據這句話就是 Action Creators,Action Creators 創建了這句話(action)之後告訴 Store,Store 接收了你要獲取數據這句話後,Store 並不知道你要什麼樣的數據,它得去查一下應該給你什麼樣的數據,到底給你什麼樣的數據。Reducer 知道應該給組件什麼樣的數據,Reducer 會按照 action 告訴 Store 應該給組件什麼樣的數據,Store 知道後會把對應的數據給到組件。
- 修改數據
如果想改變 Store 裏的數據,組件先要跟 Store 說我要改變一個數據,一樣通過 Action Creators 先說一句話(action)我要改變一個數據,Store 接收了你這句話知道你要改變數據了可是它不知道應該怎麼幫助你去改變數據,它就會去問 Reducer ,Reducer 接收了你傳過來的這句話之後,Reducer 會告訴 Store 的數據應該如何被修改,Store 修改好數據之後就會告訴組件數據修改完了你可以重新來獲取數據了,這樣組件再重新獲取最新的數據。
Store
Store 就是所有數據存儲的地方,在 react 中為一個單一數據源,你整個應用就只能有一個 store。
我們通過 Redux 提供了一個函數 createStore()
來創建 store。
// index.js
import {
createStore } from "redux";
const store = createStore(
/* function : reducer */
);
createStore
其實裡面要放一個函數的,下面我們會再提到。
如果我們想得到某一時間點的 store 數據,Redux 也提通了一個函數 getState
:
const state = store.getState();
創建好 store 之後,還有一個東西 Provider
。這是 react-redux 提供的一個組件,作用就是使其包裹的子組件都可以拿到 store 中的 state 數據。
// index.js
import {
Provider } from 'react-redux';
import {
createStore } from "redux";
const store = createStore(
/* function : reducer */
);
ReactDOM.render(
<Provider store={
store}>
<App />
</Provider>,
document.getElementById('root')
);
對於想要在任意組件中獲取某個 state 的數據,可以這麼使用:
import {
useSelector } from "react-redux";
export default function App() {
const count = useSelector((state) => state.counter.count)
return (
<div>
<h1>{
count}</h1>
</div>
)
}
Action
剛剛上面講到了 action,那我們馬上就來看看到底 action 是什麼東西。
state 的變化會導致 view 的變化,但是用戶其實接觸不到 state,用戶只跟 view 打交道,所以當然 state 的變化就必須由 view 導致。
其實 action 就只是一個簡單的 js 對象,其中有一個 type
屬性是必須的,表示的就是這個 action 的名稱,reducer 也就是根據這個 type
決定具體怎麼操縱數據,下面講到 reducer 還會說。
const action = {
type: "INCREMENT",
payload: 5,
}