iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 16
0
Modern Web

寫React的那些事系列 第 16

React Day16 - TODOS Demo(4)

  • 分享至 

  • xImage
  •  

在一開始我們定義todos的時候,留了記錄每個task是否completed的boolean(isCompleted),今天我們要再來加上這個功能,就是改變task isCompleted。

Step1


因為要改變的是todos,所以我們一樣在app.js建立function,建立非內建function,記得要到constructor去bind指定。

app.js

_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.js

TodoList這邊也把得到的props再傳給TodoItem:

list.push(
  <TodoItem
    key={idx}
    idx={idx}
    todo={todo}
    saveTask={saveTask}
    deleteTask={deleteTask}
    completeTask={completeTask}
  />);

TodoItem.js

這邊作做法和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的方式把指令都整理在一起,順手又好記!


上一篇
React Day15 - TODOS Demo(3)
下一篇
React Day17 - 在React中使用class
系列文
寫React的那些事31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言