開課程影片發現只剩下 4 個影片未觀看,著實感動啊~~~ 算一下 React 章節總共有 117 個影片,也就是說從 9/26 開始上第一節 React 之後到現在,上了一百多節課了哇哇哇。越到課程後面的影片,花時間寫筆記的時間越長,最後幾篇筆記大概都花我幾個小時寫 QQ
課程第一個挑戰是把以下 todoItem
變成 component:
<ul>
{items.map(todoItem => (
<li>{todoItem}</li>
))}
</ul>
我的做法是先創建一個 ToDoItem.jsx,然後把輸入的文字用 props 傳遞:
ToDoItem.jsx:
import React from "react";
function ToDoItem(props) {
return (
<div>
<li>{props.text}</li>
</div>
);
}
export default ToDoItem;
App.jsx:
<ul>
{items.map(todoItem => (
<ToDoItem
text={todoItem}
/>
))}
</ul>
這邊有回去看一下我之前的 map 筆記:
[Day 44] [React] Map method - 定位資料到 Components
[Day 45] [React] Map method - 練習篇! (1)
[Day 46] [React] Map method - 練習篇! (2) & HTML dictionary list
[Day 47] [JavaScript] ES6 - map & forEach
按下代辦事項,那個事項就會透過條件式渲染來畫上刪除線。
會用到的筆記有:
Ternary / AND operator
[Day 55] [React] 有 Ternary / AND operator 的條件渲染(Conditional Render)[1]
[Day 56] [React] 有 Ternary / AND operator 的條件渲染(Conditional Render)[2]
useState
[Day 60] [React] State - Hooks - useState & destructuring assignment 解構賦值
第一步是先看看如何可以讓代辦事項出現無條件刪除線,用 Google 可以查到:
Use the textDecoration property to strikethrough text in React, e.g. <span style={{textDecoration: 'line-through'}}> . The text-decoration CSS property sets the appearance of decorative lines on text. Copied! 2022年4月26日 ---How to cross out (Strikethrough) Text in React | bobbyhadz
<li style={{textDecoration: "line-through"}}>{props.text}</li>
加上之後就會發現,不論輸入什麼代辦事項,都會是有刪除線的。
再來是條件是加上 onClick,監聽點擊的狀況並用 useState 變更 value:
const [isDone, setIsDone] = useState(false);
function handleCilck(){
setIsDone((preValue) => {
return !preValue
}
)
}
return (
<div onClick={handleCilck}>
<li style={{textDecoration: "line-through"}}>{props.text}</li>
</div>
);
目前剩下要把有點擊時就渲染刪除線,否則就沒有刪除線:
原先沒有條件渲染:
<li style={{textDecoration: "line-through"}}>{props.text}</li>
現在加上條件渲染:
<li style={{textDecoration: isDone ? "line-through" : "none"}}>{props.text}</li>
final:
import React, { useState } from "react";
function ToDoItem(props) {
const [isDone, setIsDone] = useState(false);
function handleCilck(){
setIsDone((preValue) => {
return !preValue
}
)
}
return (
<div onClick={handleCilck}>
<li style={{textDecoration: isDone ? "line-through" : "none"}}>{props.text}</li>
</div>
);
}
export default ToDoItem;
如果按下去不是變成刪除線,而是從 array 裡面刪除呢?
目前的 App.jsx 裡面的 items 長這樣:
<ul>
{items.map(todoItem => (
<ToDoItem
text={todoItem}
onChecked={deleteItem}
/>
))}
</ul>
這邊 text
的 prop,用來顯示待辦事項的內容,而 onChecked
的 prop,用來處理用戶點擊事件。當用戶點擊待辦事項時,ToDoItem 會觸發 onChecked 事件,就是 {deleteItem}
啦。
接著我們要用 filter 來過濾出想要刪除的項目,然後透過 setState
方法更新 items state,讓他包含新的項目陣列。
function deleteItem(id) {
setItems(prevItems => {
return prevItems.filter((item, index) => {
return index !== id;
/*return不是點擊的 id 的 item,是點擊的id項目就不會return到
/*const [items, setItems] = useState([]); 這邊,所以點擊的項目就會消失。
});
});
}
{items.map((todoItem, index) => (
<ToDoItem
key={index}
id={index}
text={todoItem}
onChecked={deleteItem}
/>
function ToDoItem(props) {
return (
<div
onClick={() => {
props.onChecked(props.id);
}}
>
<li>{props.text}</li>
</div>
);
}
OK~~ 以上就是管理 Component tree 的課程內容,下次是這個章節的練習~