鐵人賽
React
javascript
nodejs
鐵人賽第18天,今天我們要來優化我們的ToDoApp
,讓它更好用,提升它的好用度。
Remove button
send
後,消除輸入的文字Message.js
,讓每個獨立的代辦事項,有自己的元件。bullet
前置符號,我們將原本的<div>
改為<li>
// Message.js
import React from "react";
export default function Message(props) {
return (
<li>
{props.msg} <button>{"Delete"}</button>
</li>
);
}
<li>
來顯示,當然也要針對ToDoList.js
中的<div>
改為<ul>
囉// ToDoList.js
import React, { useContext } from "react";
import { ContextStore } from "./ToDoApp";
import Message from "./Message"; //<-- 引入Message
export default function ToDoList() {
const { appReducer } = useContext(ContextStore);
const toDoList = appReducer[0];
const result = toDoList.map((e, idx) => (
<Message key={`cmd-${idx}`} msg={e} /> //<-- 改用Message component來顯示
));
return (<ul>{result}</ul>) //<--改為<ul>去顯示
}
bullet
符號,旁邊還有Remove
提供訊息的刪除toDoList
是Array
的型態吧,我們利用Day10-章節介紹的解構賦值,拷貝一份到新的 Array// reducer.js
export default function reducers(toDoList, action) {
let newToDoList = [...toDoList];
switch (action.type) {
case "ADD":
newToDoList.push(action.newEvent);
break;
// 新增Delete的部分
case "DEL":
newToDoList = newToDoList.filter(msg=>msg!==action.delMsg) // 利用filter,移除toDoList之中的delMsg
// console.log("Remove: "+action.delMsg); //<--利用console.log(), 可以快速測試是否與事件觸發連結上
break;
default:
console.log("toDoList", toDoList);
break;
}
return newToDoList;
}
Message.js
,我們將delete button
的onClick
事件與Reducer
的DEL
做個連結,讓訊息可以順利的從Array
中移除// Message.js
import React, {useContext} from "react";
import { ContextStore } from "./ToDoApp";
// 新增onClick delete事件,並與`Reducer`的`DEL`做個連結
function handleDelEvent(delMsg, dispatch) {
return (e) => dispatch({ type: "DEL", delMsg: delMsg });
}
export default function Message(props) {
const {appReducer} = useContext(ContextStore);
const dispatch = appReducer[1];
return (
<li>
{props.msg} <button onClick={handleDelEvent(props.msg, dispatch)}>{"Delete"}</button>
</li>
);
}
按下刪除前
按下刪除之後,順利的刪除囉
- 開啟
input.js
- 第一步:還記得
input
中的onChane
會存取msg
吧,而input value
剛好也是存取input框中的文字,讓這個變數跟著msg
就可以實現囉
- 第二步:我們傳遞
setMsg
到handleAddClick
func,
// input.js
import React, { useContext, useState } from "react";
import { ContextStore } from "./ToDoApp";
function handleAddClick(newMsg, dispatch, setMsg) {
const anEvent = { type: "ADD", newEvent: newMsg };
return (e) => {
setMsg(""); //<-- 給空的字串,完成清除input的動作
dispatch(anEvent);
};
}
export default function Input() {
const [msg, setMsg] = useState("");
const { appReducer } = useContext(ContextStore);
const dispatch = appReducer[1];
return (
<div>
<input
style={{ width: "150px" }}
onChange={(e) => setMsg(e.target.value)}
value={msg}
></input>
<button onClick={handleAddClick(msg, dispatch, setMsg)}>{"Send"}</button>
</div>
);
}
Chrome browser
內建的localStore
來暫存toDoList
,並在每次存取時更新它,就不用擔心重新整理後,代辦事項消失囉。// ToDoApp.js
import React, { useReducer, createContext } from "react";
import reducers from "./reducers";
import ToDoList from "./ToDoList";
import Input from "./Input";
export const ContextStore = createContext();
export default function ToDoApp() {
const appReducer = useReducer(
reducers,
localStorage.getItem("toDoList")
? localStorage.getItem("toDoList").split(",") //<-- true: 對字串做split, 可直接得到array, ex: 'aaa,bbb,ccc'=>['aaa', 'bbb', 'ccc']
: [] //<-- false: 給一個空的陣列即可
);
return (
<ContextStore.Provider value={{ appReducer: appReducer }}>
<div>
<h2 style={{ borderBottom: "1.5px black solid" }}>To Do List</h2>
<Input />
<ToDoList />
</div>
</ContextStore.Provider>
);
}
reducers.js
中,隨時更新toDoList
到localStorage
中// reducers
export default function reducers(toDoList, action) {
let newToDoList = [...toDoList];
switch (action.type) {
case "ADD":
newToDoList.push(action.newEvent);
break;
// 新增Delete的部分
case "DEL":
newToDoList = newToDoList.filter(msg=>msg!==action.delMsg) // 利用filter,移除toDoList之中的delMsg
console.log("Remove: "+action.delMsg);
break;
default:
console.log("toDoList", toDoList);
break;
}
localStorage.setItem('toDoList', newToDoList) //<-- 讓browser能夠暫存這筆資料,重新整理就不用擔心資料遺失囉
return newToDoList;
}
Google Chrome inspector的console
看看,輸入localStorage.toDoList
,不錯,確實有存進去喔!Message
一個獨一無二的值,並在Reducer DEL
進行判斷處理,這部分就交給各位練習看看!ToDoApp
,提升app
的使用者體驗。app
,過程中,我們將所學的複習運用,相信各位對React
都更加熟練了。超棒的你~繼續Rock!!