回到部落格
2024-02-27
【React作品集】Todo List專案 part.4

原文發表於 Medium。
今天我們要來加入既有Todo事項的修改功能。若您是第一次到這來,請先至:【React作品集】Todo List專案 part.1 。

我們這次要達成的效果如上面的GIF所示,點選既有todo項目,就可以修改內容,並且儲存起來。
我們就先從架構開始吧,其實這個功能不難達成,在正式修改前需要確認下列幾點:
1. 點選了todo項目之後啟動修改,點選其他項目時切換到該項目
2. 以input輸入的方式修改內容,在點選時把原有的資料倒入input中
3. 按鈕隨著啟動修改後轉變功能
啟動修改項目
點選todo後打開編輯功能還算好達成,首先由於todo項目都是裝在一個array裡面,我們要先確認點選的項目的index是多少,然後按圖索驥,去把點選到項目改成input而不是單純的文字text。
const [editingTodoIndex, setEditingTodoIndex] = useState<number | null>(null);
......
return
......
{/*渲染todo列表資料*/}
{todos.map((todo, index) => { //map函數的第二個參數是每個單獨元件的index
return (
<div className="todoItem" key={todo.timeStamp}>
<input type="checkbox" />
{/*修改的重點,把裝上onClick,然後內部分成input跟span*/}
<p
onClick={() => {
setEditingTodoIndex(index); //把點選的元件index存入state
}}
>
{/*三元運算子 當元件的index對應到客戶點選的元件時,切換為input,否則,則為span的內容。*/}
{editingTodoIndex === index ? (
<input
/>
) : (
<span>{todo.text}</span>//裝在span裡面的文字方便跟input置換
)}
</p>
這樣就可以做出切換input跟text的功能了。
抓取input內容,並把原有資料倒入input作為初始資料
創立一個新的useState用來存input狀況,並針對input做資料雙向綁定。
const [editingTodoIndex, setEditingTodoIndex] = useState<number | null>(null);
const [editTodoValue, setEditTodoValue] = useState("");
......
return
......
{/*渲染todo列表資料*/}
{todos.map((todo, index) => {
return (
<div className="todoItem" key={todo.timeStamp}>
<input type="checkbox" />
<p
onClick={() => {
setEditingTodoIndex(index);
setEditTodoValue(todo.text); //把元件原有的內容存成state
}}
>
{editingTodoIndex === index ? (
<input
value={editTodoValue} //連結到state
onChange={(e) => {
setEditTodoValue(e.target.value); //使用useState,所以要手動雙向綁定
}}
/>
) : (
<span>{todo.text}</span>//裝在span裡面的文字方便跟input置換
)}
</p>
按鈕隨著啟動修改後轉變功能

在todo項目右方的按鈕,我們需要把他的功能跟標示模式切換要達到這樣的效果一樣要透過萬用的「三元運算子」來處理:
<button
//把onClick的功能隨著是否選中來切換成編輯與刪除功能。
onClick={() => {
{
editingTodoIndex === index //用index確認是否是被選中的項目,同上面的input/span相同
? editTodoHandler(editTodoValue, index)
: deleteTodoItemHandler(todo.timeStamp);
}
}}
>
{editingTodoIndex === index ? "修改" : "刪除"} //切換字面顯示功能
</button>;
上面屢屢用到的三元運算子功能,各位一定要熟習,因為在React中這是很重要的技巧。
至此,我們簡單的Todo list專案就基本完成了,接下來各位可以依照自己的喜愛,使用CSS等style工具來為這個素面的APP做一些裝飾。
希望大家喜歡這一系列的文章,下回我想要推出一個購物網站的DEMO,敬請期待唷!