前幾天已經寫好todolist的邏輯、樣式,現在我們的程式已經可以新增、瀏覽、刪除代辦事項,並且有簡單的外觀。
不過新增的事項還沒辦法編輯,因此今天來做一下編輯的功能。
首先要先抓出對應的項目,由於之前已經把id
傳入到項目中了,要抓出對應的項目相當容易。
先做一個edit的按鈕,並排好位置。用Stack
作排列:
// List
<Stack direction="horizontal" gap={3}>
<Card.Link href="#">
edit
</Card.Link>
<Card.Link href="#" onClick={deleteHandler}>delete
</Card.Link>
</Stack>
再來,在List中
寫一個偵測狀態的state:
const [isEdit, setIsEdit] = useState("");
這邊說明一下,這個isEdit
要偵測的是id
值,要是有某個項目edit的按鈕被按下,就set那個項目的id
值進state。
接下來要更改一下JSX的部分,如果isEdit
沒有東西或比對id失敗,則保持不變;若isEdit有id
值,且跟項目的id
值比對成功,則顯示編輯的input
。
// List
const list = item.map((i, index)=>{
const {content, id} = i;
return(
<div key={id}>
{/*使用三元運算子比對id*/}
{!(isEdit === id) ? (
<Card>
{/*...*/}
</Card>) : (
{/*要是id比對成功,顯示編輯輸入格*/}
<InputGroup className="my-3">
<Form.Control type="text" defaultValue={content}/>
<Button>提交</Button>
</InputGroup>
)}
</div>)
}
接著要寫程式邏輯,當對某個項目按edit
時,要讓isEdit
的值變成該項目的id。
// List
<Card.Link href="#" onClick={()=>{setIsEdit(id)}}>
edit
</Card.Link>
isEdit
變成id後,整個component會重新render,同id的項目就會變成編輯區塊。
編輯完成後,我們需要讓編輯出來的值更新到item
中,並render出來;此外,也需要讓編輯狀態變回一般狀態。
首先,先新增一個偵測編輯區塊的state:
const [newInput, setNewInput] = useState("");
// …edit block
<Form.Control type="text" onChange={(e)=>{setNewInput(e.target.value)}} defaultValue={content}/>
接著,當”修改”按鈕被按下時,更改item
內容並更新到item state上,並將編輯狀態改回一般狀態:
// List
const editedHandler=(e)=>{
{/*新建item Array */}
const newItem = item.map(i=>{
const {id, content} = i;
{/*如果id符合,更改content內容*/}
if(id === isEdit){
i.content = newInput;
return i;
}
{/*若不符合,回傳原值*/}
return i;
})
{/*更新編輯狀態、item state*/}
setIsEdit("");
setItem(newItem);
}
這樣就完成了!這個todolist小程式已經有新增、瀏覽、編輯、刪除的功能,接著要幫我們的小程式增加已完成、未完成的狀態轉換,讓todolist具有事項檢核的功能!
codepen