一步一步用 React Redux 編寫一個 Todo App

原文地址: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ì)朋其,寫的最好的教程王浴,因為它把每一步怎么做,思路都寫出來了梅猿,受益良多氓辣,因此翻譯出來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袱蚓,一起剝皮案震驚了整個濱河市钞啸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喇潘,老刑警劉巖体斩,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颖低,居然都是意外死亡絮吵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進(jìn)店門忱屑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹬敲,“玉大人暇昂,你說我怎么就攤上這事“槲耍” “怎么了急波?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闹究。 經(jīng)常有香客問我幔崖,道長,這世上最難降的妖魔是什么渣淤? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任赏寇,我火速辦了婚禮,結(jié)果婚禮上价认,老公的妹妹穿的比我還像新娘嗅定。我一直安慰自己,他們只是感情好用踩,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布渠退。 她就那樣靜靜地躺著,像睡著了一般脐彩。 火紅的嫁衣襯著肌膚如雪碎乃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天惠奸,我揣著相機(jī)與錄音梅誓,去河邊找鬼。 笑死佛南,一個胖子當(dāng)著我的面吹牛梗掰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗅回,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼及穗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绵载?” 一聲冷哼從身側(cè)響起埂陆,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娃豹,沒想到半個月后猜惋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡培愁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年著摔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片定续。...
    茶點(diǎn)故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡谍咆,死狀恐怖禾锤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情摹察,我是刑警寧澤恩掷,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站供嚎,受9級特大地震影響黄娘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜克滴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一逼争、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劝赔,春花似錦誓焦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仍翰,卻和暖如春赫粥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背予借。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工越平, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕾羊。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像帽驯,于是被迫代替她去往敵國和親龟再。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容