# Redux

[github](https://github.com/reduxjs/react-redux)      [doc](https://redux.js.org/)      [中文doc](https://cn.redux.js.org/)

### 資料的基本流程

![](https://703864731-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LGT_WSMJJJ-6nRhUva4%2F-LGcqspVAZiOLl6nmPFQ%2F-LGcsazWFM8OqYRcHOmo%2Fimage.png?alt=media\&token=089d8977-af8a-4448-9115-0f3381d17bfb)

### 三大原則&#x20;

1. 只使用一個store將整個應用程式的狀態(state)用物件樹(object tree)的方式儲存起來 redux只有一個store，使用reducer functions負責每個小部分的管理（在整個store 內）<br>
2. 唯一可改變這個state的方法就是發送action action就只是一個物件，帶入action type和參數 而實際因應action裡的內容對state做變化的函式就叫reducer<br>
3. .因為redux框架的設計，所以所有計算新state的functions（也就是reducers）都 必須是 pure function 因為都是pure function，所以很容易debug！甚至是time-travelling between state

{% hint style="info" %}
application’s state is immutable 代表任意組件(Component)都可以修改（非修改原有的state，參考下面那句） immutable 代表不可修改的，所以redux通過 reducer functions去產生新的state去取代 舊的state\
immutable 代表不可修改的，所以redux通過reducer functions去產生新的state去取代舊的state
{% endhint %}

### 架構&#x20;

* store - json object&#x20;
* constant - 固定參數，通常action的type我都會寫在這
* action - function，必須包含type
* reducer - 有兩個參數，分別為舊有的state和action。而reducer回傳的就是更新後的 state&#x20;
* component and container

component vs container 如下圖 ([圖片來源](https://redux.js.org/basics/usage-with-react#presentational-and-container-components))

![](https://703864731-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LGT_WSMJJJ-6nRhUva4%2F-LGcqspVAZiOLl6nmPFQ%2F-LGcuWWFixohZSlmjdps%2Fimage.png?alt=media\&token=9e46e90f-417b-47fb-9ba5-12a88c6ad5ec)

> 簡單說，處理有關邏輯跟store的獲取、存取、變動等動作的component，稱為 container component\
> 單純處理 props 顯示在螢幕上的長相（ui），稱作 presentational component\
> react-redux提供了一個簡單的工具 connect，簡單和快速的寫出container

{% hint style="info" %}
詳細介紹可參考此 [網站](https://medium.com/@imranhishaam/react-native-with-redux-for-beginners-6281959a2899)
{% endhint %}

&#x20;&#x20;

### 常用方法（以下皆可到上方提供的doc內看）

#### &#x20;redux&#x20;

* &#x20;createStore - 傳入reducer，簡單的創建store redux 為 single store，此 createStore 方法在應用內應該只會被呼叫過一次<br>
* combinReducers - 因某些原因（結構、模塊化等..）將reducer拆分成多個單獨的函數，拆分後的每 個函數負責獨立管理state的一部分。combinReducers的作用就是，把由多個不同reducer 函數作為value的object合併為一個最終的reducer函數，然後就可以對這個reducer調用 createStore方法<br>
* applyMiddleware - 使用middelware<br>
* &#x20;binActionCreators - 傳入 actions和dispatch。使用dispatch對每個action進行包裝，以便可以直接調用他們

#### react-redux

* Provider - 在應用內，負責將唯一的store傳給其他子元件<br>
* connect -  方法需要一些參數(第一個 () 內)，但大多數時候我們只需要前兩個參數(mapStateToProps 和 mapDispatchToProps)(Component) \
  maptStateToProps 和 mapDispatchToProps 這兩個fun會回傳兩個Object，將這兩個Object整理成Props然後丟進Component內

{% hint style="info" %}
maptStateToProps - 將store內的state轉成js object作為參數傳入該container(也就是該container的props)。 透過此來選取container需要state的哪一部分 \
\
mapDispatchToProps - 此參數型態必須是function。將store的dispatch()當作參 數傳入該container(也就是該container的props)
{% endhint %}

### 跟Store交互的方法

1. dispatch(action) - 直接向store發出一個action
2. getState() - 獲取現在app內的整個store state

&#x20;

### Middleware&#x20;

* redux-thunk
* &#x20;redux-logger
* redux-persist
* redux-saga
* ....

### 實作範例&#x20;

* [Counter](https://github.com/chentsulin/react-native-counter-ios-android)
* Todo List

### 參考

* [React Native Taiwan Meetup #002](https://www.youtube.com/watch?v=6kgHlvAGFLY\&feature=youtu.be)

{% hint style="info" %}
redux 下有一個store ，為json格式，但因為很大，所以有reducer把store去做切片，然後在index組成一個大的object\
Container 一個描述你的Component跟哪些reduer的切片和哪些Action有關係=> 就是利用 export connect(mapStateToProps, mapDispatchToProps)(Component); 中的 mapStateToProps和mapDispatchToProps這兩個fun會回傳2個Object，將這兩個Object整理成你的Props然後丟進Component內
{% endhint %}

{% hint style="warning" %}
此 connec t為 heighr-order function 和 heighr-order component，很推薦去暸解！
{% endhint %}
