經過一個todolist 大概的瞭解React的 組件的書寫過程,下面是一個todolist的代碼:javascript
import React from 'react'; // TodoList 組件是一個總體的組件,最終的React渲染也將只渲染這一個組件 // 該組件用於將『新增』和『列表』兩個組件集成起來,而且存儲 todolist 的數據 var TodoList = React.createClass({ // 初始化數據 getInitialState: function () { return { todolist: [] }; }, // 接收一個傳入的數據,並將它實時更新到組件的 state 中,以便組件根據數據從新render // 只要改變了 state ,react自動執行 reader 計算 handleChange: function (rows) { this.setState({ todolist: rows }); }, render: function () { return ( <div> {/* 集成 TypeNews 組件,傳入兩個屬性 onAdd 和 todo todo - 將todolist的數據傳入到組件,當新增時,更新todolist數據 onAdd - 將 handleChange 函數傳入到組件,新增時,用它來處理最新的todolist數據 */} <TypeNew onAdd={this.handleChange} todo={this.state.todolist} /> {/* 集成 ListTodo 組件,傳入兩個屬性 onDel 和 todo todo - 將todolist的數據傳入到組件,當刪除時,更新todolist數據 onDel - 將 handleChange 函數傳入到組件,刪除時,用它來處理最新的todolist數據 */} <ListTodo onDel={this.handleChange} todo={this.state.todolist} /> </div> ); } }); // TypeNew 組件用於新增數據,它須要 todo 和 onAdd 兩個屬性,上文已經提到過 // 基本邏輯是:當從 input 中獲取數據時,將新數據 push 到todo中, // 而後使用 onAdd 調用 TodoList 的 handleChange 來更新state,而後react自動render var TypeNew = React.createClass({ handleAdd: function (e) { e.preventDefault(); // 經過 refs 獲取dom元素,而後獲取輸入的內容 var inputDom = this.refs.inputnew.getDOMNode(); var newthing = inputDom.value.trim(); // 獲取傳入的todolist數據 var rows = this.props.todo; if (newthing !== '') { // 更新數據,並使用 onAdd 更新到 TodoList 組件的 state 中 rows.push(newthing); this.props.onAdd(rows); } inputDom.value = ''; }, render: function () { return ( // form submit 時,觸發 handleAdd 事件 <form onSubmit={this.handleAdd}> <input type="text" ref="inputnew" id="todo-new" placeholder="typing a newthing todo" autoComplete="off" /> </form> ); } }); // ListTodo 組件用於展現列表,並能夠刪除某一項內容,它有 noDel todo 兩個屬性,上文已經提到過 // 它的基本邏輯是:遍歷 todo 的內容,生成數據列表和刪除按鈕 // 對某一項執行刪除時,想將 todo 中的數據刪除, // 而後經過 onDel 事件調用 TodoList 的 handleChange 來更新state,而後react自動render var ListTodo = React.createClass({ handleDel: function (e) { var delIndex = e.target.getAttribute('data-key'); // 更新數據,並使用 onDel 更新到 TodoList 的 state 中,以便 React自動render this.props.todo.splice(delIndex, 1); this.props.onDel(this.props.todo); }, render: function () { return ( <ul id="todo-list"> { // {/* 遍歷數據 */} this.props.todo.map(function (item, i) { return ( <li> <label>{item}</label> <button className="destroy" onClick={this.handleDel} data-key={i}>delete</button> </li> ); }.bind(this)) // {/* 綁定函數的執行this - 以便 this.handleDel */} } </ul> ); } }); export default TodoList;
React提倡全部的數據都是由父組件來管理,經過props的形式傳遞給子組件來處理——要點。java
作一個todolist頁面須要一個父組件,兩個子組件。父組件固然就是todolist的『總指揮』,兩個子組件分別用來add和show、delete。用通俗的方式講來,父組件就是領導,兩個子組件就是協助領導開展工做的,一切的資源和調動資源的權利,都在領導層級,子組件配合領導工做,須要資源或者調動資源,只能申請領導的批准。數據徹底由父組件來管理和控制,子組件用來顯示、操做數據,得通過父組件的批准,即——父組件經過props的形式將數據傳遞給子組件,子組件拿到父組件傳遞過來的數據,再進行展現。react
另外,根據React開發的規範,組件內部的數據由state控制,外部對內部傳遞數據時使用 props 。這麼看來,針對父組件來講,要存儲todolist的數據,那就是內部信息(自己就是本身可控的資源,而不是『領導』控制的資源),用state來存儲便可。而父組件要將todolist數據傳遞給子組件,對子組件來講,那就是傳遞進來的外部信息(是『領導』的資源,交付給你來處理),須要使用props。dom
而todolist的數據是由父組件來管理的,子組件不能說改就改呀,得申請父組件的容許和贊成呀。所以,咱們須要讓父組件開放一個能夠修改數據的接口,而後將這個接口做爲props傳遞給子組件,讓其能修改數據。子組件調用父組件的接口對todolist數據進行修改了以後,至關於修改了React對象的state數據,此時就會觸發React的自動更新(就是經過virtual-dom對比,而後更新真實的dom那一套),React會將UI實時隨着數據更新。函數