在一開始我們定義todos的時候,留了記錄每個task是否completed的boolean(isCompleted),今天我們要再來加上這個功能,就是改變task isCompleted。
因為要改變的是todos,所以我們一樣在app.js建立function,建立非內建function,記得要到constructor去bind指定。
_completeTask(idx) {
let newTodos = [...this.state.todos];
newTodos[idx] = Object.assign({}, newTodos[idx], { isCompleted: !newTodos[idx].isCompleted });
this.setState({ todos: newTodos });
}
再把這個function傳給TodoList:
<TodoList
todos={this.state.todos}
saveTask={this._saveTask}
deleteTask={this._deleteTask}
completeTask={this._completeTask}
/>
TodoList這邊也把得到的props再傳給TodoItem:
list.push(
<TodoItem
key={idx}
idx={idx}
todo={todo}
saveTask={saveTask}
deleteTask={deleteTask}
completeTask={completeTask}
/>);
這邊作做法和delete其實一樣,在render {todo.task}時,設定span並且加上onClick事件,讓click動作執行props傳來的completeTask functin。
<span onClick={() => completeTask(idx)}>
{todo.task}
</span>
不過,這樣雖然已經改變task的isCompleted狀態,但畫面上卻沒有因此有樣式的變化,所以我們要加上style來區分已完成與尚未完成的task。React設定style的方式,是用一個object,裡面的key值採用camelCase的寫法,例如:font-size要寫成fontSize、background-color要寫成backgroundColor。
這邊我們用到兩個屬性,color與text-decoration:
const taskStyle = {
color: todo.isCompleted ? '#888' : '#000',
textDecoration: todo.isCompleted ? 'line-through' : ''
};
完整的render程式碼如下:
render() {
const { todo, idx, deleteTask, completeTask } = this.props;
const taskStyle = {
color: todo.isCompleted ? '#888' : '#000',
textDecoration: todo.isCompleted ? 'line-through' : ''
};
if (this.state.isEditing) {
return (
<tr>
<td><input type="text" data-idx={idx} defaultValue={todo.task} ref="editInput" /></td>
<td>
<button onClick={this._onSaveClick}>Save</button>
<button onClick={this._onCancelClick}>Cancel</button>
</td>
</tr>
);
}
return (
<tr>
<td>
<span style={taskStyle} onClick={() => completeTask(idx)}>
{todo.task}
</span>
</td>
<td>
<button onClick={this._onEditClick}>Edit</button>
<button onClick={() => deleteTask(idx)}>Delete</button>
</td>
</tr>
);
}
加上切換task的功能是不是很簡單呢!用JSX來寫component的方式也很簡單易懂,從code裡面就可以大概知道畫面架構會長什麼樣子,今天的原始檔已經放在Git上。
在開發的過程中,我們使用webpack-dev-middleware+webpack-hot-middleware來實現hot reload,可以減少許多開發時間。等到開發完成,要進入production階段時,我們執行webpack把檔案bundle出來,執行下面的指令,就會發現資料夾多了build,而裡面也產生bundle.js。
// --progress 會顯示打包進度
// --colors 會幫 webpack 顯示的訊息加入顏色
webpack --progress --color
而我們也可以把production的指令,同樣寫在package.json的script裡
"scripts": {
"prod": "webpack --progress --color"
}
這樣我們就可以用下面的指令來執行
npm run prod
後面幾天應該還會介紹到test的方式,也會把指令整合在package.json的script裡,透過package.json的方式把指令都整理在一起,順手又好記!