2024-02-23
【React作品集】Todo List專案 part.2

原文發表於 Medium。
本次,我們要來改變Todo List資料流的狀態,並產生與使用者間的互動機制。若您是第一次到這來,請先至:【React作品集】Todo List專案 part.1 開始看起。
加入刪除功能
首先我們先來實裝刪除功能,在App.tsx的 App函數中加入一個刪除單個todo項目的handler,之後修改刪除的按鈕的onClick:
function deleteTodoItemHandler(timeStamp: string) {
setTodos((prev) => prev.filter((item) => item.timeStamp !== timeStamp));
}
<button
onClick={deleteTodoItemHandler.bind(this, todo.timeStamp)}
>
刪除
</button>
也可使用.bind()將timestamp傳入handler,範例如下。(我個人不推)
<button
onClick={() => {
deleteTodoItemHandler(todo.timeStamp);
}}
>
刪除
</button>
```
我們來看看效果:

加入新Todo
緊接著,我們就來看看怎麼加入新的Todo項目:
第一步,先求有再求好,我們要讓ok按鈕被按下時,加入一個新的item到列表裡面,把下面的handler加入到ok按鈕的onClick屬性:
function addTodoItemHandler() {
const newTodo: TodoItem = {
//把Date的值使用toISOString來轉成類似"2024-02-23T08:00:00"這樣的格式
timeStamp: new Date().toISOString(),
text: "測試",
checked: false,
};
setTodos((prev) => [...prev, newTodo]);
}
```順便把OK button改一下,不然按了沒反應唷。下面是文字示意
<button onClick={addTodoItemHandler}>OK</button>
```

*如果測試的item按下就全部刪除的話,那就是加入timeStamp的設定有問題,請仔細看上面的程式碼。
使用客戶輸入的資料
一般來說,我們都會使用useState或useRef這兩個hook來抓取客戶的輸入值,此處我使用useRef:
//由於使用的是TypeScript,因此需要標註ref的內容型別
const userInputRef = useRef<HTMLInputElement>(null);
```JS版本如下
const userInputRef = useRef(null);
```
我們需要修改addTodoItemHandler,並且把userInputRef綁定到<input>中:
function addTodoItemHandler() {
//擋住客戶為輸入資料就按下OK按鈕的狀況。
if (!userInputRef.current?.value) {
alert("請輸入內容");
return null;
}
//把text內容設定到ref的當前值,雖然前面已經設定了空值防護,但還是保險一點設定一個空值輸入。
const newTodo: TodoItem = {
timeStamp: new Date().toISOString(),
text: userInputRef.current?.value || "",
checked: false,
};
setTodos((prev) => [...prev, newTodo]);
//把input清空,增加使用者體驗!小細節,但很重要!
userInputRef.current!.value = "";
}
看看效果:

到此,我們的Todo List可以新增資料、刪除資料,就有了初步的雛形了!非常恭喜!希望這個過程讓你感受到創造事物的美好感覺。
但很抱歉地潑一盆冷水,目前這個Web App還是不能用的,因為網頁重新整理後,資料又全部歸零了!這樣是無法達成Todo List的紀錄功能的。
因此加上『記憶功能』就是我們下一部分要處理的,加油!我們快完成了!