# Reducer 基礎概念
就像 [Reducers](../../basics/Reducers.md) 中描述的一樣,一個 Redux reducer 函數需要具備:
- 應該有類似 `(previousState, action) => newState` 特征的函數,函數的類型與 [Array.prototype.reduce(reducer, ?initialValue)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) 這個函數很相似。
- 應該是"純"函數,純函數意味著不能突變(原文 mutate,意指直接修改引用所指向的值)它的參數,如果在函數中執行 API 調用,或者在函數外部修改值,又或者調用一個非純函數比如 `Date.now()` 或 `Math.random()`,那么就會帶來一些副作用。這意味著 state 的更新應該在**"不可變(immutable)"**的理念下完成,這就是說**總是去返回一個新的更新后的對象**,而不是直接去修改原始的 state tree。
> ##### 關于不可變(immutability)和突變(mutation)以及副作用
>
> 突變是一種不鼓勵的做法,因為它通常會打亂調試的過程,以及 React Redux 的 `connect` 函數:
>
> - 對于調試過程, Redux DevTools 期望重放 action 記錄時能夠輸出 state 值,而不會改變任何其他的狀態。**突變或者異步行為會產生一些副作用,可能使調試過程中的行為被替換,導致破壞了應用。**
> - 對于 React Redux `connect` 來說,為了確定一個組件(component)是否需要更新,它會檢查從 `mapStateToProps` 中返回的值是否發生改變。為了提升性能,`connect` 使用了一些依賴于不可變 state 的方法。并且使用淺引用(shallow reference)來檢測狀態的改變。這意味著**直接修改對象或者數組是不會被檢測到的并且組件不會被重新渲染。**
>
> 其他的副作用像在 reducer 中生成唯一的 ID 或者時間戳時也會導致代碼的不可預測并且難以調試和測試。
因為上面這些規則,在去學習具體的組織 Redux reducer 的技術之前,了解并完全理解下面這些核心概念是十分重要的。
#### Redux Reducer 基礎
**核心概念**:
- 理解 state 和 state shape
- 通過拆分 state 來確定各自的更新職責(**reducer 組合**)
- 高階 reducers
- 定義 reducer 的初始化狀態
**閱讀列表**:
- [Redux 文檔: Reducer](../../basics/Reducers.md)
- [Redux 文檔: Reducer 樣板代碼](../ReducingBoilerplate.md)
- [Redux 文檔: 實現撤銷歷史](../ImplementingUndoHistory.md)
- [Redux 文檔: `combineReducers`](../../api/combineReducers.md)
- [高階 Reducer 的力量](http://slides.com/omnidan/hor#/)
- [Stack Overflow: Store 初始化 state 和 `combineReducers`](http://stackoverflow.com/questions/33749759/read-stores-initial-state-in-redux-reducer)
- [Stack Overflow: State 鍵的名稱與 `combineReducers`](http://stackoverflow.com/questions/35667775/state-in-redux-react-app-has-a-property-with-the-name-of-the-reducer)
#### 純函數和副作用
**核心概念**:
- 副作用
- 純函數
- 如何理解組合函數
**Reading List**:
**閱讀列表**:
- [關于函數式編程的一點兒小想法](http://jaysoo.ca/2016/01/13/functional-programming-little-ideas/)
- [理解程序的副作用](http://web24studios.com/2015/10/understanding-programmatic-side-effects/)
- [學習 Javascript 中的函數式編程](https://youtu.be/e-5obm1G_FY)
- [使用純函數編程的理由](https://www.sitepoint.com/an-introduction-to-reasonably-pure-functional-programming/)
#### 不可變數據的管理
**核心概念**:
- 可變與不可變
- 安全地以不可變的方式更新對象和數組
- 避免在函數和語句中突變 state
**閱讀列表**
- [在 React 中使用 Immutable 特性的優缺點](http://reactkungfu.com/2015/08/pros-and-cons-of-using-immutability-with-react-js/)
- [Javascript 和 Immutable 特性](http://t4d.io/javascript-and-immutability/)
- [使用 ES6 的 Immutable 數據及其延伸](http://wecodetheweb.com/2016/02/12/immutable-javascript-using-es6-and-beyond/)
- [Immutable 數據從零開始](https://ryanfunduk.com/articles/immutable-data-from-scratch/)
- [Redux 文檔: 使用對象展開符](../UsingObjectSpreadOperator.md)
#### 范式化數據
**核心概念**:
- 數據庫的組織結構
- 拆分相關/嵌套數據到單獨的表中
- 為每個被賦值的對象都存儲一個單獨的標識
- 通過 ID 引用對象
- 通過對象 ID 來查找表,通過一組 ID 來記錄順序
- 通過關系來聯系各個對象
**閱讀列表**:
- [用簡單的英語介紹數據庫范式化](http://www.essentialsql.com/get-ready-to-learn-sql-database-normalization-explained-in-simple-english/)
- [Redux 慣用法: 范式化 State Shape](https://egghead.io/lessons/javascript-redux-normalizing-the-state-shape)
- [范式化文檔](https://github.com/paularmstrong/normalizr)
- [讓 Redux 變得更干凈:范式化](https://tonyhb.gitbooks.io/redux-without-profanity/content/normalizer.html)
- [查詢 Redux Store](https://medium.com/@adamrackis/querying-a-redux-store-37db8c7f3b0f)
- [維基百科: 關聯實體](https://en.wikipedia.org/wiki/Associative_entity)
- [數據庫設計: 多對多](http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php)
- [當組織你的應用 State 時避免不必要的復雜度](https://medium.com/@talkol/avoiding-accidental-complexity-when-structuring-your-app-state-6e6d22ad)
- 自述
- 介紹
- 動機
- 核心概念
- 三大原則
- 先前技術
- 學習資源
- 生態系統
- 示例
- 基礎
- Action
- Reducer
- Store
- 數據流
- 搭配 React
- 示例:Todo List
- 高級
- 異步 Action
- 異步數據流
- Middleware
- 搭配 React Router
- 示例:Reddit API
- 下一步
- 技巧
- 配置 Store
- 遷移到 Redux
- 使用對象展開運算符
- 減少樣板代碼
- 服務端渲染
- 編寫測試
- 計算衍生數據
- 實現撤銷重做
- 子應用隔離
- 組織 Reducer
- Reducer 基礎概念
- Reducer 基礎結構
- Reducer 邏輯拆分
- Reducer 重構示例
- combineReducers 用法
- combineReducers 進階
- State 范式化
- 管理范式化數據
- Reducer 邏輯復用
- 不可變更新模式
- 初始化 State
- 結合 Immutable.JS 使用 Redux
- 常見問題
- 綜合
- Reducer
- 組織 State
- 創建 Store
- Action
- 不可變數據
- 代碼結構
- 性能
- 設計哲學
- React Redux
- 其它
- 排錯
- 詞匯表
- API 文檔
- createStore
- Store
- combineReducers
- applyMiddleware
- bindActionCreators
- compose
- react-redux 文檔
- API
- 排錯