用 React.js 寫一個最簡單的 To-do List 應用

最近在學 React.js,也寫了一些練習的項目,以前參考網上的一些代碼寫了一個很簡單的 to-do list。對於初學者來講,寫個基本的 to-do list 對於理解 React 中的一些概念及語法卻是挺有幫助的。javascript

如今不少的 React 項目中已經開始使用 ES6 來寫了,不過由於我在學習 React 的時候看的教程大多都是用 ES5 寫的,我這裏仍是用的仍是更熟悉的 ES5 寫法,雖然有點落伍了,但若想改爲 ES6 版本倒也挺方便的。css

GitHub 上的項目地址
在線 demohtml

clipboard.png

文件目錄

在正式的生產項目中,使用 webpack 能夠很方便地對咱們的文件進行打包,這裏由於程序比較簡單,直接用 <script> 標籤將 React 組件引入了。java

首先新建一個 index.html 文件,引入相關的資源文件。python

再新建一個 js 文件夾,咱們使用 React 須要這樣的兩個文件: react.jsreact-dom.js,你可使用 cdn 引入,這裏直接將文件下載放在了 js 文件夾內。react

js 文件夾內還有一個 script.jsx 文件,咱們程序的主要內容就放在這個文件中。注意這裏的後綴名是 jsx,表示它是使用 React 的 jsx 語法來寫的,引入它的時候按以下寫法:webpack

<script type="text/babel" src="js/script.jsx"></script>

同時還須要一個 browser.js 文件,它可讓 jsx 語法的文件在瀏覽器中運行。git

最後咱們再創建一個 css 文件夾,存放樣式文件,個人項目中使用了 Bootstrap 的樣式,因此須要下載 Bootstrap 的樣式文件。github

程序功能

做爲一個最簡單的 to-do list,這個程序沒有過多的功能。能夠從 demo 裏看出,它的功能以下:web

  • 顯示每個任務

  • 能夠將任務標記爲已完成,以區分未完成的任務

  • 加入任務 / 刪除任務

  • 統計任務總數和完成的任務數量

做爲一個示例程序,以上就是它的功能了。

組件結構

咱們可使用 React 開發出各類組件(component),利用不一樣組件的功能來實現一個應用。咱們這裏建立的組件有:

TodoBox
    -TodoList
        -TodoItem
        -TodoFooter
    -TodoForm
  • TodoBox 是最外層的組件,其他的都是它的子組件

  • TodoList 是各個單獨的待辦任務的集合

  • TodoItem 即爲一條單獨的待辦事項

  • TodoFooter 對上述的事項進行統計

  • TodoForm 用於加入新的項目

屬性的傳遞

React 的組件有兩種不一樣的屬性,stateprops。能夠用一種簡單的方法來區分它們:若是這個屬性是其父組件傳給它的,那麼就是 props,反之若是一個屬性是組件本身的,那麼就是 state

具體何時用 state,何時用 props,能夠參考這幾條:

  • Is it passed in from a parent via props? If so, it probably isn't state.

  • Does it change over time? If not, it probably isn't state.

  • Can you compute it based on any other state or props in your component? If so, it's not state.

參考來源:Thinking in React

這裏咱們從代碼來看看,屬性是如何從父組件傳遞到子組件的。

每一條待辦事項有這樣的幾個屬性:

  • id: 任務的編號

  • task: 任務的具體內容

  • complete: 任務是否已經完成

咱們看看屬性的傳遞過程。

首先在 TodoBox 組件的 state 中有一個 data 對象:

data: [
    {"id": "0001", "task":"吃飯", "complete": "false"},
    {"id": "0002", "task":"睡覺", "complete": "true"},
    ...
  ]

TodoBox 組件的 render 函數中會有 TodoList 組件:

<TodoList data={this.state.data}
    // 其餘的屬性及方法寫在這裏
  />

這樣 TodoBox 組件的 data 屬性就傳遞給了子組件 TodoBox。在 TodoBox 中經過 this.props 來引用這一屬性,即 this.props.data

TodoBox 組件還有子組件 TodoItem,能夠將屬性繼續傳遞下去。在 TodoList 組件的 render 函數中這樣寫:

var taskList = this.props.data.map(function(listItem) {
      return (
        <TodoItem
          taskId={listItem.id}
          key={listItem.id}
          task={listItem.task}
          complete={listItem.complete}
          // 其餘的屬性及方法
      )
    }, this);

TodoItem 組件中就能夠用 this.props.taskId 得到任務的 id 了。

函數的傳遞

咱們的程序中須要的函數有這幾個:

  • handleTaskDelete: 根據id刪除一項任務

  • handleToggleComplete: 切換一項任務的完成狀態

  • handleSubmit: 新增一項任務

  • generateId: 給新增的任務一個隨機的id

在 React 的組件中傳遞方法與傳遞屬性相似,如今 TodoBox 組件中有一個 handleToggleComplete 函數,將它傳遞給 TodoList 組件:

<TodoList toggleComplete={this.handleToggleComplete}
    // 其餘的屬性及方法寫在這裏
  />

這樣你就能夠在 TodoList 組件中經過 this.props.toggleComplete 來調用這一方法了,你也能夠將這一方法繼續向下一層的組件傳遞。

程序的運行

你能夠下載 GitHub 上的項目文件,再用 python 開啓一個 HTTP 服務器,就能夠打開 http://localhost:8000/ 查看運行結果了。

git clone https://github.com/noiron/simplest-react-todolist.git
cd simplest-react-todolist
python -m SimpleHTTPServer // open a server with python

這篇博客裏沒有對整個項目全部的代碼進行分析,更多內容仍是直接看代碼更清楚。

博客原地址:http://www.wukai.me/2016/06/1...

相關文章
相關標籤/搜索