原文地址:Step by Step Guide To Building React Redux Apps
項目地址:react-redux-todoApp / redux
第一步: 對 App 做一個詳細(xì)的模擬
模擬應(yīng)該包括數(shù)據(jù)和虛擬效果(比如 todo 條目的刪除線契沫,或者過濾器選中 “All” 時硝枉,不應(yīng)該顯示鏈接的下劃線)。
注意: 你可以點(diǎn)擊下面的圖片放大或者縮小。

便簽紙上的內(nèi)容為:
步驟一: 對每個屏幕都做一個模擬
如何做:
1.盡可能地詳細(xì)
2.保證所有的數(shù)據(jù)和虛擬的效果(比如 todo 條目的刪除線)
第二步:將 App 分成幾個部分
根據(jù)整體的“目的”嚎杨,嘗試將 App 拆分成塊座云。
我們將 todo App 拆分成三塊: “AddTodo”、“TodoList”旁理、“Filter”樊零。

便簽紙上的內(nèi)容為:
步驟二:將 App 拆分成塊
如何做:基于整個目的將他們分拆,這是一個 App 常用的粗略的方法和大致的塊孽文。
我們的 Todo App 有三個主要目的:
1.添加一個新的 Todo 條目(AddTodo component)
2.展示 Todo 條目的列表(TodoList component)
3.展示過濾的 Todo 條目(Filter component)
Redux 術(shù)語: “Action” 和 “State”
每個 component 都需要做兩件事情:
1驻襟,基于數(shù)據(jù)渲染 DOM,這些數(shù)據(jù)稱為“state”芋哭。
2.監(jiān)聽用戶和其他事件沉衣,并且將它們傳給 JS 函數(shù)。這些叫做“Action”楷掉。
第三步:每個 “ Component” 列表的 “state” 和 “Action”
仔細(xì)看第二步的每個部分厢蒜,并且列出它們的 “State” 和 “Action”霞势。
我們有三個部分:“AddTodo”, “TodoList”斑鸦, “Filter” 愕贡,讓我們來分別列出它們各自的 “Action” 和 “State”。
3.1 AddTodo Component 的 “State” 和 “Action”
在這個部分巷屿,沒有 “state”固以,因為這個部分看起來沒有基于任何數(shù)據(jù)的改變,但是它需要其他部分知道用戶什么時候創(chuàng)建了一個新的 todo嘱巾,我們把這個 “action” 叫做 “ADD_TODO”憨琳。

便簽紙上的內(nèi)容為:
AddTodo component
state:
這是一個簡單的區(qū)域,展示它不需要基于任何的數(shù)據(jù)旬昭。
Actions(Events)
AddTodo component 允許我們創(chuàng)建一個新的 todo 條目篙螟,通過監(jiān)聽 DOM 的事件,并從輸入框重新渲染數(shù)據(jù)问拘。
在這個例子中遍略,我們可以通過創(chuàng)建一個 JSON 對象來描述這個 AddTodo action ,并且像下面這樣添加數(shù)據(jù):
{
type: "ADD_TODO"
payload: {data: "Learn Redux", id:"1", completed: false}
}
3.2 TodoList Component 的 State 和 Actions
TodoList component 需要一個 Todo 條目的新的數(shù)組去渲染它自己骤坐,所以它需要一個 state绪杏,我們叫它 Todos(數(shù)組)。同時也需要知道選擇某個 “Filter” 時纽绍,哪個 Todo 條目需要展示蕾久, 這需要另外一個 state,我們叫它 “VisibilityFilter”(布爾)拌夏。
另外僧著,還需要允許我們能夠轉(zhuǎn)換 Todo 條目的狀態(tài),使其完成或者沒有完成障簿。我們需要讓其他組件知道我們轉(zhuǎn)換的操作霹抛。我們把這個 action 稱為 “TOGGLE_TODO”。

3.3 Filter Component 的 State 和 Actions
Filter 組件基于是否是 active 的一個鏈接或者是簡單文本來渲染卷谈。我們稱這個 state 為 “CurrentFilter”杯拐。
Filter 組件也需要讓其他組件知道用戶什么時候點(diǎn)擊了它,這個 action 稱為“SET_VIBILITY_FILTER”世蔗。

Redux 術(shù)語:Action Creators
Action Creators 是一些簡單的函數(shù)端逼,它的作用就是從 DOM 事件中數(shù)據(jù),它是一個 JSON 格式的 “Action” 對象并且返回這個對象(又稱為 “Action”)污淋。這可以幫助我們將 data/payload 形式化顶滩。
另外,它允許任何其他的組件將這些 actions 傳遞(又稱為 dispatch)給其他組件寸爆。
第四步:為每個 Action 創(chuàng)建 Action Creators
我們總共又三個 actions: ADD_TODO礁鲁, TOGGLE_TODO盐欺,SET_VISIBILITY_FILTER。讓我們?yōu)樗鼈兠總€創(chuàng)建 create actions仅醇。
//1. Takes the text from AddTodo field and returns proper “Action” JSON to send to other components.
export const addTodo = (text) => {
return {
type: ‘ADD_TODO’,
id: nextTodoId++,
text, //<--ES6. same as text:text, in ES5
completed: false //<-- initially this is set to false
}
}
//2. Takes filter string and returns proper “Action” JSON object to send to other components.
export const setVisibilityFilter = (filter) => {
return {
type: ‘SET_VISIBILITY_FILTER’,
filter
}
}
//3. Takes Todo item’s id and returns proper “Action” JSON object to send to other components.
export const toggleTodo = (id) => {
return {
type: ‘TOGGLE_TODO’,
id
}
}
Redux 術(shù)語: Reducers
Reducers 是一些函數(shù)冗美,它接收從 Redux 傳來的 “state” 和 “action” JSON 對象。并且返回一個新的 “state”析二,存儲回 Redux 中粉洼。
1.Reducer 函數(shù)稱為 “Container”,當(dāng)用戶觸發(fā)了 “action”叶摄。
2.如果 reducer 改變了 state属韧, Redux 傳遞一個新的 state 給每個組件,并且重新渲染組件蛤吓。
For example the below function takes Redux’ state(an array of previous todos), and returns a **new** array of todos(new state) w/ the new Todo added if action’s type is “ADD_TODO”.
const todo = (state = [], action) => {
switch (action.type) {
case ‘ADD_TODO’:
return
[…state,{id: action.id, text: action.text, completed:false}];
}
第五步:為每一個 Action 寫 Reducers
為了簡化教程宵喂,只展示其中一個。
const todo = (state, action) => {
switch (action.type) {
case ‘ADD_TODO’:
return […state,{id: action.id, text: action.text,
completed:false}]
case ‘TOGGLE_TODO’:
return state.map(todo =>
if (todo.id !== action.id) {
return todo
}
return Object.assign({},
todo, {completed: !todo.completed})
)
case ‘SET_VISIBILITY_FILTER’: {
return action.filter
}
default:
return state
}
}
Redux 術(shù)語: “Presentational” 和 “Container” 組件
保持每個組件中 React 和 Redux 的內(nèi)在邏輯可能會混亂会傲,所以 Redux 提倡創(chuàng)建一個展示組件(Presentational)——僅供展示數(shù)據(jù)樊破,和一個父容器組件(Container)——包含Redux,發(fā)送“Actions”或更多功能唆铐。
父容器組件傳遞數(shù)據(jù)給展示組件,控制事件奔滑,處理展示組件中的 React艾岂。

圖例: 黃色虛線 = 展示組件,黑色虛線=容器組件
第六步: 完善每個展示組件
6.1 完善 AddTodoForm 的展示組件

6.2 完善 TodoList 展示組件

6.3 完善 Link 展示組件

第七步: 為每個展示組件創(chuàng)建容器組件
7.1 創(chuàng)建容器組件——AddTodo

7.2 創(chuàng)建容器組件——TodoList

7.3創(chuàng)建容器組件——Filter

第八步: 將它們合在一起
import React from ‘react’ // ← Main React library
import { render } from ‘react-dom’ // ← Main react library
import { Provider } from ‘react-redux’ //← Bridge React and Redux
import { createStore } from ‘redux’ // ← Main Redux library
import todoApp from ‘./reducers’ // ← List of Reducers we created
//Import all components we created earlier
import AddTodo from ‘../containers/AddTodo’
import VisibleTodoList from ‘../containers/VisibleTodoList’
import Footer from ‘./Footer’ // ← This is a presentational component that contains 3 FilterLink Container comp
//Create Redux Store by passing it the reducers we created earlier.
let store = createStore(reducers)
render(
<Provider store={store}> ← The Provider component from react-redux injects the store to all the child components
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
</Provider>,
document.getElementById(‘root’) //<-- Render to a div w/ id "root"
)
我的感想:這個教程是我目前見到的最詳細(xì)朋其,寫的最好的教程王浴,因為它把每一步怎么做,思路都寫出來了梅猿,受益良多氓辣,因此翻譯出來。