最近在學 React.js,也寫了一些練習的項目,以前參考網上的一些代碼寫了一個很簡單的 to-do list。對於初學者來講,寫個基本的 to-do list 對於理解 React 中的一些概念及語法卻是挺有幫助的。javascript
如今不少的 React 項目中已經開始使用 ES6 來寫了,不過由於我在學習 React 的時候看的教程大多都是用 ES5 寫的,我這裏仍是用的仍是更熟悉的 ES5 寫法,雖然有點落伍了,但若想改爲 ES6 版本倒也挺方便的。css
在正式的生產項目中,使用 webpack 能夠很方便地對咱們的文件進行打包,這裏由於程序比較簡單,直接用 <script>
標籤將 React 組件引入了。java
首先新建一個 index.html
文件,引入相關的資源文件。python
再新建一個 js
文件夾,咱們使用 React 須要這樣的兩個文件: react.js
和 react-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 的組件有兩種不一樣的屬性,state
和 props
。能夠用一種簡單的方法來區分它們:若是這個屬性是其父組件傳給它的,那麼就是 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.
這裏咱們從代碼來看看,屬性是如何從父組件傳遞到子組件的。
每一條待辦事項有這樣的幾個屬性:
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
這篇博客裏沒有對整個項目全部的代碼進行分析,更多內容仍是直接看代碼更清楚。