昨天我們完成了To-Do List的React專案靜態刻畫,昨天的codesandbox連結在這邊,今天要讓我們的To-Do List動起來。
認識我們的第一個React hooks function
useState 定義 state 變量時候,它返回一個有兩個值的陣列。第一個值是當前的 state,第二個值是更新 state 的函數。每當 state 值改變,就會觸發 re-render。
參考資料:React 使用 State Hook
這邊先用簡單的計數器方式來介紹useState
import React, { useState } from 'react';
function Counter() {
// 聲明一個叫做 "count" 的 state 變數,初始值為0
const [count, setCount] = useState(0);
return (
<div className="Counter">
{/* 顯示count現在增加或減少的當下數字*/}
<h2>You clicked {count} times!</h2>
{/* 當你點選Decrement的按鈕,計數器的數量就會從現有的數字增加1*/}
<button onClick={() => setCount(count - 1)}>Decrement</button>
{/* 當你點選Increment的按鈕,計數器的數量就會從現有的數字減少1*/}
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
React計數器的前端顯示畫面如下:
它定義一個「state變數」,這邊我的變數叫count,也可以被取做任何名字,例如:apple, orange,這是一種函數在調用時保存變數的方式,useState是一種方法,而state中的變數會被React保留。
useState()方法裡面唯一的參數就是初始state,在上方計數器的範例中,只需使用數字來記錄使用者的點擊次數,所以我傳了0作為變數的初始state,如果想要在 state 中儲存兩個不同的變數,只需調用useState()兩次即可。
返回值為:當前state以及更新的state函數。這就是寫const [count, setCount] = useState()的原因。
接下來進到我們的To-Do List專案中設置我們useState狀態
import React, { useState } from 'react'
import "./App.css"
const App = () => {
// 初始化我們input輸入框為空字串
const [inputToDo, setInputToDo] = useState("")
// 初始化我們待辦清單的所有內容為空陣列
const [toDoList, setToDoList] = useState([])
// 新增待辦事項的按鈕函數
const handleSubmit = (e) => {
// 當我們點選Add按紐時handleSubmit會被觸發
// 我們不希望它刷新頁面
e.preventDefault();
// 只要inputToDo裡面不是空字串
// 就會創建新的To-Do List
if (inputToDo !== "") {
setToDoList([{ id: `${inputToDo}-${Date.now()}`, inputToDo }, ...toDoList])
}
}
return (
<div className="App">
<div className='container'>
{/* 標題 */}
<h1>To-Do List</h1>
{/* 待辦事項的輸入表單,提交按鈕觸發handleSubmit函式 */}
<form className='toDoForm' onSubmit={handleSubmit}>
{/* 新增待辦事項的輸入框,onChange每當輸入框改變時調用 */}
<input type="text" onChange={(e) => setInputToDo(e.target.value)}/>
{/* 新增按鈕 */}
<button>Add</button>
</form>
{/* 待辦清單顯示內容,t代表整個對象為輸入框內的inputToDo值 */}
<ul className='allToDoList'>
{toDoList.map((t) => (
<li className='singleTodoTask'>
<span className='toDoText'>{t.inputToDo}</span>
<button>Update</button>
<button>Delete</button>
</li>
))}
</ul>
</div>
</div>
)
}
export default App
結果如下圖所示,可以看到我在輸入框輸入待辦事項的文字並按下新增按鈕後,下方會動態出現我剛新增的內容。
新增後會發現我們的console面板跳出Error訊息
Warning: Each child in a list should have a unique "key" prop.
Check the render method of `App`. See https://reactjs.org/link/warning-keys for more information.
at li
at App (https://myw15j.csb.app/src/App.js:27:41)
錯誤訊息是在說,新增的,我們沒有提供給它獨立的key,這邊需要修改的地方如下顯示,為它加上我們上方創建的id。
<li className="singleTodoTask" key={t.id}>
今天完成了新增按鈕的動態作法,明天接續來完成刪除按紐的部分。
今天的程式碼我會放在codesandbox上。
這是我第一次參加鐵人賽,希望透過這30天督促自己脫離菜味,內容預計會有JS基礎,API串接,用React完成一個可以新增、修改、刪除、查詢的網站,如果有錯誤歡迎指正,我會盡快修改。