# 下一步
如果你學到了這一章,你也許會想:接下來我該干什么?下面我們會為你提供一些建議,教你如何從 todo 級別的應用過度到真實世界中的項目。
## 實際項目中的建議和考慮
每當我們決定要建立一個新項目時,我們總是很容易忽略一些問題,這些問題在未來有可能影響性能。而在實際項目的開發之前我們必須把一些事情決策清楚,比如說:如何配置 `store`、`store` 的大小、數據結構、state 模型、中間件(middleware)、環境、異步操作、不可變性......,等等。
上面提及的這些決定是需要我們事先想清楚的。雖然任務艱巨,但實施一些策略可以讓決策更加順利。
### UI vs State
使用 Redux 時,開發者面臨的最大挑戰之一就是**用數據描述 UI**。大多數軟件都是數據(data)換了一種形式的呈現。而且你要知道,UI 只不過是數據用一種漂亮的方式的呈現。理解了這一點,你構建應用時就會得心應手。
在 “[Describing UI state with data](http://nicolashery.com/describing-ui-state-with-data/)” 一文中 **Nicolas Hery** 把這個道理闡釋得很好。而且你應該知道 **[在何時使用 Redux](https://medium.com/@fastphrase/when-to-use-redux-f0aa70b5b1e2)**,因為很多時候 **[你并不需要 Redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367)**
### 配置 Store
配置 `store` 時我們需要決定使用哪些 middleware。關于這點有很多庫,其中最受歡迎的有:
#### 異步 dispatch
- [redux-thunk](https://github.com/gaearon/redux-thunk)
- Redux Thunk middleware 允許你編寫返回一個函數的 action creator,而不再返回 action。Thunk 可被用于推遲一個 action 的 dispatch,或者只在特定條件滿足時 dispatch。它會將 `dispatch` 和 `getState` 作為參數傳遞。
- [redux-saga](https://github.com/redux-saga/redux-saga)
- redux-saga 是一個庫旨在讓應用的“副作用”的執行更方便高效,例如異步訪問數據或讀取瀏覽器緩存這樣的不純操作。同時 redux-saga 很易于測試,因為它使用了 ES6 `generators` 特性,讓代碼流看起來像同步代碼一樣方便閱讀。
- [redux-observable](https://github.com/redux-observable/redux-observable)
- redux-observable 是一個 redux middleware,它受 redux-thunk 啟發。開發者使用它可以 dispatch 一個函數,這個函數可以返回 `Observable`,`Promise`,或 `iterable` 對象。當 observable 對象發出(emit)一個 action,或 promise 對象 resolve 了一個 action,或 iterable 返回了一個對象時,這個對象才會像平時一樣被 dispatch。
#### 開發環境 / 調試
- [redux-devtools](https://github.com/reduxjs/redux-devtools)
- Redux DevTools 是一系列幫助你開發 Redux 的工具。
- [redux-logger](https://github.com/evgenyrodionov/redux-logger)
- redux-logger 會記錄下所有 dispatch 到 store 的所有 action。
要決定選擇什么庫,我們需要考慮應用的規模。同時也要考慮可用性,代碼規范,以及對 Javascript 的熟練程度。選擇的原則大同小異。
**小提示**:把 middleware 想象為賦予 `store` 的各種**技能**。例如:給 store 添加 `redux-thunk`,相當于 store 擁有了 dispatch 異步 action 的技能。
### 命名規范
在一個大項目中,命名會帶來巨大的困惑,通常命名和寫代碼一樣重要。在項目剛剛開始時,最好制定一套 action 的命名規范,并在之后的開發中嚴格遵守。當項目范圍逐漸增大時,這將非常有助于你的代碼的擴張。
非常好的文章:
[A Simple Naming Convention for Action Creators in Redux](https://decembersoft.com/posts/a-simple-naming-convention-for-action-creators-in-redux-js/)
和
[Redux Patterns and Anti-Patterns](https://tech.affirm.com/redux-patterns-and-anti-patterns-7d80ef3d53bc)
**小提示**:使用一個代碼格式化工具,比如 [Prettier](https://github.com/prettier/prettier)。
### 擴容性
沒有一種方法可以分析和預測你的項目會增長到什么程度,但沒關系!因為 Redux 簡潔的設計打下了堅實的基礎,它可以在項目增長的過程中自適應。下面的一些文章介紹了一些方法,可以讓你以優雅的姿勢編寫應用:
- [Taming Large React Applications with Redux](http://slides.com/joelkanzelmeyer/taming-large-redux-apps#/)
- [Real-World React and Redux - part l](https://dzone.com/articles/real-world-reactjs-and-redux-part-1)
- [Real-World React and Redux - part ll](https://dzone.com/articles/real-world-reactjs-and-redux-part-2)
- [Redux: Architecting and scaling a new web app at the NY Times](https://www.youtube.com/watch?v=lI3IcjFg9Wk)
**小提示**:在動手之前確實應該做好計劃,但也不要陷入[“紙上談兵”](https://en.wikipedia.org/wiki/Analysis_paralysis)。畢竟“做完”比“完美做完”更好,而且如果需要的話,[Redux 的重構起來很容易](https://blog.boldlisting.com/so-youve-screwed-up-your-redux-store-or-why-redux-makes-refactoring-easy-400e19606c71)
總之,最好的實踐永遠是 keep coding and learning。參與 [issues](https://github.com/reduxjs/redux/issues) 和 [StackOverFlow questions](https://stackoverflow.com/questions/tagged/redux) 的討論也是一種精通 Redux 的好辦法。
**小提示**:@markerikson 在 [react-redux-links](https://github.com/markerikson/react-redux-links) 中分享了更多最佳實踐和 Redux 架構。
- 自述
- 介紹
- 動機
- 核心概念
- 三大原則
- 先前技術
- 學習資源
- 生態系統
- 示例
- 基礎
- 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
- 排錯