iT邦幫忙

2021 iThome 鐵人賽

DAY 30
0
Modern Web

看初心者怎麼學React系列 第 30

Day30 實作todoList(五)完成刪除事項功能+完賽心得

畫面完成後,該怎麼從List.js的迴圈元件中的按鈕去互叫function,
讓function去改變App.js中的State資料呢?

刪除事項和完成事項功能

我們需要在App.js檔案中建立刪除事項和完成事項的function,再利用props將兩個function傳List元件中,List便可以使用function來改變App.js中的資料了。

刪除項目function

//App.js 

/*刪除項目function*/
//點擊刪除按鈕後會回傳點擊項目的key到index參數中
  const deleteItem = function (index) {
//篩選留下key和index不同的項目,變相就是刪除選中項目
    const list = todoList.filter((item) => item['key'] !== index)
//將項目變更後的List存回TodoList
    setTodoList(list)
  }

完成項目function

//App.js  

/*完成項目function*/

	//點擊完成按鈕後會回傳點擊項目的key到index參數中
  const doneItem = function (index) {
	
  //用maa查詢每個陣列項目,如果key和index相同,將done的值變true
    const list = todoList.map(function (item) { 
		if (item['key'] === index) item['done'] = true; 
		return item 
		})
	//將項目變更後的List存回TodoList
    setTodoList(list)
  }

用物件形式把兩個function包起來,通過props傳到List.js給

//App.js 

return (
    <div className="App">
      <Header />
      <div className="container">
        <Input />
        <div className="list-wrapper">
					//透過props.fuc傳入function
          <List show={todoList} fuc={{ deleteItem, doneItem }} />
        </div>
      </div>
    </div>
  )

在List.js的itemloop之中就能使用function改變資料了

//List.js

const itemLoop = function (list) {
        const deleteItem = prop.fuc.deleteItem
        const doneItem = prop.fuc.doneItem

        return list.map((item) => {
            return (<div key={item.key}>
                <div className="flex item-wrap">
                    <p>{item.content}</p>
                    <div className="flex center gap-10">
			//元件dom不能綁JavaScript event,所以在外層用div包住Button使用
			//記得傳入事項的key到參數中
                      <div onClick={() => deleteItem(item.key)}>
						<Button content="刪除" type="detele" />
                      </div>
                        <div style={btnDisplay} 
                            onClick={() => doneItem(item.key)}>
                            <Button content="完成" />
						</div>
                    </div>

                </div>
                <hr />
            </div>)
        })
    }

待辦和完成分頁

最後一個步驟,我要將事項用done的boolean值來分成
已完成的事項list、未完成的事項list
用useLocation()的pathname判斷路由,來傳入不一樣的list

//App.js
import { useLocation } from 'react-router-dom';

//  待辦和未完成分別的list
  function doneList(list) {
    return list.filter((item => {
      return item.done && !item.delete
    }))
  }

  function undoList(list) {
    return list.filter((item) => {
      return !item.done && !item.delete
    })
  }

//根據路由傳入不同資料給List.js
const location = useLocation()
const changeFun = location.pathname === '/undo' ? undoList(todoList) : doneList(todoList)

return (
    <div className="App">
      <Header />
      <div className="container">
        <Input />
        <div className="list-wrapper">
					//傳入不同資料到List元件中
          <List show={changeFun} fuc={{ deleteItem, doneItem }} />
        </div>
      </div>
    </div>
  )

這樣就能切換待辦和完成事項頁面了!
測試的預設State可以移除改為空陣列[],讓一進畫面時沒有資料顯示。

全部的程式碼放在以下網址的github上,可以拿去參考
https://github.com/Cheng-sih-rong/todolist-react

實際頁面
https://cheng-sih-rong.github.io/todolist-react/index


完賽心得

祝我們組順利的完成挑戰!要是沒有親愛的組員們在群組裡更新進度,我恐怕第五天就放棄了吧QQ。
這漫長的30天,也就這樣熬過去了,雖然筆記有很多不足的地方,但透過這三十天,
不僅是認真學習了一個新的框架React,相信自己做筆記的速度和能力也有進步,收穫非常多,很慶幸有參加鐵人賽!
這一個月每天下班後都在家水深火熱的趕文章(沒有庫存自作孽),
結束後總算鬆口氣了~接下來幾天要放空讓大腦休息一下,yeah!!!

感謝我的組員們一起同甘共苦撐過去,你們最棒了!之後還要一起學習更多程式喔!

下面分享組員們的超棒文章,大家辛苦啦!

我的Vue學習筆記
https://ithelp.ithome.com.tw/users/20140300/ironman/4132

這個網站也太嗨!30 個網頁動態提案
https://ithelp.ithome.com.tw/users/20140247/ironman/4150


上一篇
Day29 實作todoList(四)產生事項列表
系列文
看初心者怎麼學React30

1 則留言

0
liawyudye
iT邦新手 5 級 ‧ 2021-10-16 14:33:53

恭喜完賽!晚上終於可以不用感文章囉~~

Taco iT邦新手 5 級 ‧ 2021-10-17 23:33:13 檢舉

yeah~~我們做到了!

我要留言

立即登入留言