iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Modern Web

用React讓網頁動起來: React基礎與實作系列 第 13

[Day13]用React讓網站動起來:todo list 實作-完成、未完成切換

  • 分享至 

  • xImage
  •  

今天要繼續實作todolist,要讓todolist有切換已完成、未完成狀態的功能。

程式修正

昨天的編輯功能出了點問題,若是在沒修改的情況下提交,由於newInput沒東西,所以會變成空值。
今天來修正一下,將newInput加入條件控制,並在提交後重設newInput

// List.js
  const editedHandler=(e)=>{
    const newItem = item.map(i=>{
      const {id, content} = i;
		// newInput要有東西才修改content
      if(id === isEdit && newInput){
        i.content = newInput;
        return i;
      }
      return i;
    })
	// 重置newInput
    setNewInput("");
    setIsEdit("");
    setItem(newItem);
  }

更改樣式

由於項目要render的東西越來越多,我們把它取出來獨立成component:

// Item.js
const Item = ({content, id, setIsEdit, item, setItem})=>{
	// 把deleteHandler移入這裡
    const deleteHandler = (e)=>{
    	e.preventDefault();
		// 可以取得id,直接取id
    	const newItem = item.filter(element=> element.id !== id);
    	setItem(newItem);
  }

  return (
    <Card>
      {/*…*/}
    </Card>
  )
}
// List.js
const List = ({item, setItem})=>{
	// …
  const list = item.map((i, index)=>{
    const {content, id} = i;
    return(
      <div key={id}>
		{/*將content、id、setIsEdit、item、setItem傳入Item*/}
        {!(isEdit === id) ? <Item content={content} id={id} setIsEdit={setIsEdit} item={item} setItem={setItem}/> : (<InputGroup className="my-3">
     <Form.Control type="text" onChange={(e)=>{setNewInput(e.target.value)}} defaultValue={content}/>
    <Button onClick={editedHandler}>提交</Button>
    </InputGroup>)}
     </div>)
  }
  )
  return (
    <div>
      {list}
    </div>
  )
}

接著,處理一下架構,在Item中加入checkbox,將Card.BodyForm.Check component包起來:

// Item.js

<Card>
<Form.Check type="checkbox" id={`check-${id}`} className="d-flex align-items-center">
	{/*加上Form.Input,才會出現checkbox*/}
        <Form.Check.Input type="checkbox" className="m-0" onClick={checkHandler}/>
		{/*用Form.Check.Label把整個Card.Body包起來*/}
        <Form.Check.Label className="w-100">
          <Card.Body id={id} className="d-flex justify-content-between">{
			{/*…*/}
      	  </Card.Body>
     	</Form.Check.Label>
    </Form.Check>
</Card>

程式邏輯

接下來要加上程式邏輯,一樣要用state去做。在Item上加上isDone的state。

// Item.js

const [isDone, setIsDone]= useState(false);

當checked時,isDone切換成true,反之則false:

// Item.js
const checkHandler = (e)=>{
      if(e.target.checked){
        setIsDone(true);
      }else{
        setIsDone(false);
      };
    }

// …
<Form.Check>
<Form.Check.Input type="checkbox" className="m-0" onClick={checkHandler}/>
</Form.Check>

接著讓內容在完成時畫一條刪除線,一樣用三元運算子控制:

// Item.js
<Card.Body id={id} className="d-flex justify-content-between">
   <span className={isDone ? "text-decoration-line-through" : ""}>{content}</span>
{/*…*/}
</Card.body>

https://ithelp.ithome.com.tw/upload/images/20220928/20146829dNlKMF0ewA.png

這樣就能完成完成事項的效果。然而,這只是樣式改變而已,沒有真正儲存到已完成、未完成的狀態。明天會儲存已完成、未完成的內容,並且製作分頁來顯示已完成、未完成的事項。


上一篇
[Day12]用React讓網站動起來:todolist實作-編輯todolist
下一篇
[Day14]用React讓網站動起來:todolist實作-已完成、未完成分頁
系列文
用React讓網頁動起來: React基礎與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言