快開天窗了先把目前進度 po 出來再說orz
今天文章重點在 setState 搭配 ...prev
的運用~
當我今天想要做一個偶像挑選器(?),
要怎麼做?
首先我先新增一個檔案 idolItems.js
,
裡面放上各個偶像的名字跟圖片網址,
像這樣:
export const idolList = [
{
playerName: "戴資穎",
picture:
"https://im.marieclaire.com.tw/m800c533h100b0/assets/mc/202108/6106B3F21135F1627829234.jpeg"
},
... (略)
然後我再新增一個 Game.js
,
裡面要 import idolItems.js
的 idolList component,
並利用 <ul> <li>
搭配 .map
把 idolList 陣列裡面一個一個元素各別把名字跟圖片顯示出來,
重點是要在 <li>
綁上 value={index}
的屬性,
這樣之後才能拿來點擊後判斷用,
像這樣:
import React, { useState } from "react";
import { idolList } from "./idolItems.js";
export const Game = () => {
};
return (
<>
<h2>你的偶像是:</h2>
{answerList.map((answer) => (
<>
<div>{idolList[answer].playerName}</div>
<img
width="100px"
src={idolList[answer].picture}
alt={idolList[answer].name}
/>
</>
))}
<h2>請點選你喜歡的偶像(名字):</h2>
<ul>
{idolList.map((idol, index) => (
<>
<li value={index} onClick={handleChange}>
{idol.playerName}
</li>
<img width="100px" src={idol.picture} alt={idol.name} />
</>
))}
</ul>
</>
);
};
再來重頭戲來了,
我想要點選名字上面就出現我的點選結果要怎麼做?
首先我先宣告 answerList,以及相對應設值的 setAnswer,
並將初始值設為空陣列,
像這樣:
const [answerList, setAnswer] = useState([]);
再來要宣告一個 handleChange 的 function,
在點擊 <LI>
要執行,
這邊先貼程式:
const handleChange = (event) => {
if (event.target.nodeName === "LI") {
setAnswer((prev) => {
return [event.target.value, ...prev];
});
}
};
這邊的重點有兩個,
...prev
setAnswer((prev) => {
return [event.target.value, ...prev];
});
這邊的意思是將 setAnswer 所對應到的 state answerList 陣列裡面的內容存為 ...prev
,
再來我要 append 一個新元素到 answerList 陣列只需要這樣寫 新的值,...prev
即可,
如果沒有寫 ...prev 的話則每次只要你一點擊就會把 answerList 重新蓋掉。
其實 ...prev 應該是 JavaScript 的語法,
只是我到現在才知道怎麼用orz XD
Spread syntax (...)
event.target.nodeName
if (event.target.nodeName === "LI")
}
為什麼要加這個,因為我剛剛在 <li>
裡面放了圖片的元件,
然後只要點擊到圖片,
就會出現 error,
這個原因是因為只有 <li>
有 value={index}
,
當你點擊到 <img>
因為 event.target.value
為空,
(prev) => {
return [event.target.value, ...prev];
})
所以在處理這句會發生錯誤哦!
這邊為大家示範一下沒加出現的錯誤訊息:
也因此只有點到 <li>
上的文字才會處理哦!
這應該也算是 exception handling (例外處理) 的一種,
這很重要哦!
哦對,然後當然要記得在 App.js
加入 <Game />
的 component 哦,
像這樣:
[App.js]
<div className="App">
<Game />
</div>
那我們來看看成果:
附上本日程式:Day25 - useState (Codecademy)
差點趕不上又遇到 bug orz
超驚險QQ
發文前在寫前端又參考了我前幾天發的文章XD
覺得勵志XD