雖然昨天的文章有提到我想在 Codecademy 開始打 React 的基礎,
不過看前幾天我的文章順序是 認識 useState、熟悉 useState、認識 useEffect,
所以今天應該要排一個熟悉 useEffect XD
而剛好看到一個我之前沒注意到的 component,
所以就順便來個綜合練習吧~~~
今天要為大家介紹的 component 是 Spinners,
看到這樣的色系不覺得會讓人聯想到奧運的五環圖案嗎XD
所以我今天想要用 Spinners 來弄奧運的圖示XD
Spinners 去查中文意思會發現有旋轉球, 穿針引線, 紡線者的意思,
總之在網頁的世界看到 Spinners 就表示這種會旋轉的 loading 圖示。
然後一開始我在 CodeSandbox 貼以下範例程式時,
不知道為什麼中間會多 Loading 的字樣= ="
<div>
<Spinner color="secondary" />
<Spinner color="success" />
<Spinner color="danger" />
<Spinner color="warning" />
<Spinner color="info" />
<Spinner color="light" />
<Spinner color="dark" />
</div>
所以我只好把範例改寫成這樣:
<div>
<Spinner color="info">{' '}</Spinner>
<Spinner color="dark">{' '}</Spinner>
<Spinner color="danger">{' '}</Spinner>
<Spinner color="warning">{' '}</Spinner>
<Spinner color="success">{' '}</Spinner>
</div>
參考奧運五環圖案,
所以挑了 info, dark, danger, warning, success 這五個顏色,
你看這樣是不是就很有奧運五環圖案的 fu 了XD
再來當然要善用 Flex 把這五個環排成跟奧運五環一樣的位置,
首先把五個環拆成兩個 <div>
,
然後我又在兩個 <div>
外面包了一個 <div>
,
並限制寬度(因為不要讓它們以瀏覽器整個寬度去排版),
(PS. 這邊我有另外寫 CSS 處理:
.container {
width: 12rem;
}
所以在 App.js 記得 import CSS:
import "./styles.css";
)
再來就在 padding, margin 上做一點裝飾,
完成品如下:
<div className="container px-4 mt-2">
<div className="px-2 d-flex justify-content-between">
<Spinner color="info"> </Spinner>
<Spinner color="dark"> </Spinner>
<Spinner color="danger"> </Spinner>
</div>
<div className="px-4 d-flex justify-content-around">
<Spinner color="warning"> </Spinner>
<Spinner color="success"> </Spinner>
</div>
</div>
到這邊排版的部份就告一段落,
再來就是為了也要練習 useState, useEffect,
我想了一下,決定弄成2020東京奧運佳績榜,
一開始畫面顯示「載入中......」,
倒數 3 秒後才會顯示下方的奧運佳績榜,
這樣要怎麼做呢?
首先先把最後想呈現畫面刻出來,
先不要想邏輯,
像這樣:
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import React, { useState, useEffect } from "react";
import { Spinner } from "reactstrap";
import "./styles.css";
export default function App() {
return (
<>
<div className="container px-4 mt-2">
<div className="px-2 d-flex justify-content-between">
<Spinner color="info"> </Spinner>
<Spinner color="dark"> </Spinner>
<Spinner color="danger"> </Spinner>
</div>
<div className="px-4 d-flex justify-content-around">
<Spinner color="warning"> </Spinner>
<Spinner color="success"> </Spinner>
</div>
</div>
<div className="m-4">
<h3 className="text-center">2020東京奧運佳績榜</h3>
<p className="text-center">載入中......</p>
<div>
<h4>?金牌</h4>
<ul>
<li>舉重女子59公斤級:郭婞淳</li>
<li>羽球男子雙打:李洋、王齊麟</li>
</ul>
<h4>?銀牌</h4>
<ul>
<li>羽球女子單打:戴資穎</li>
<li>競技體操男子鞍馬:李智凱</li>
<li>柔道男子60公斤(含)以下級:楊勇緯</li>
<li>射箭男子團體賽:湯智鈞、魏均珩、鄧宇成</li>
</ul>
<h4>?銅牌</h4>
<ul>
<li>跆拳道女子49-57公斤級:羅嘉翎</li>
<li>舉重女子64公斤級:陳玟卉</li>
<li>拳擊女子51公斤蠅量級:黃筱雯</li>
<li>空手道:文姿云</li>
<li>高爾夫男子個人比桿賽:潘政琮</li>
<li>桌球混合雙打:林昀儒、鄭怡靜</li>
</ul>
</div>
</div>
</>
);
}
再來思考一下這樣該怎麼做:
倒數 3 秒後才會顯示下方的奧運佳績榜
相信大家對 setTimeout 並不陌生,
setTimeout 就是可以設定幾秒後執行 function,
(setInterval 則是設定每幾秒就執行一次 function)
因此像這樣的 setTimeout 這樣的 function,
也是 useEffect 的服務範圍,
就是當頁面(組件)渲染後且會有變化就要執行,
所以我們先在 useEffect 寫上 setTimeout:
useEffect(() => {
setTimeout(() => {
}, 3000);
});
(3000 就是 3 秒後要執行裡面 function 的意思)
想一下我們 3 秒後要執行的動作:
所以前面先這樣宣告:
const shortText = "載入中......";
const longText = "2金-4銀-6銅";
const [text, setText] = useState(shortText);
const [isShow, setIsShow] = useState(false);
前面三行是狀態文字的部份,
第四行是為了要控制奧運佳績榜的顯示與否。
(預設值當然是 false)
這樣答案很明顯了,
我們要在 setTimeout 裡面寫 setText 及 setIsShow,
像這樣:
useEffect(() => {
setTimeout(() => {
setText(longText);
setIsShow(true);
}, 3000);
});
但你發現奧運佳績榜從一開始就會出現,
要怎麼讓它一開始不出現,3 秒後才出現?
這邊要介紹一個 React 的語法,
直接寫在網頁元素中,
架構長這樣:
{ 變數(條件) ? (
<div>
...
...
</div>
): null }
這個意思是,會去判斷 變數(條件),
true 的話會顯示 ? (...) 的內容,
false 的話則會顯示 : 後面的內容。
(PS. : 後面設定 null 就是空值,也就是當 false 時不要顯示任何內容)
所以我們在奧運佳績榜那段要這樣改寫:
{isShow ? (
<div>
<h4>?金牌</h4>
<ul>
<li>舉重女子59公斤級:郭婞淳</li>
<li>羽球男子雙打:李洋、王齊麟</li>
</ul>
...
...(略)
</div>
) : null}
然後在上面的 <p className="text-center">載入中......</p>
也要記得改寫成這樣才會在倒數 3 秒前後產生不同變化:<p className="text-center">{text}</p>
讓我們來看看成果:
是不是很有趣!!!!!!
用 useState, useEffect 就可以產生這樣的變化!
尤其我覺得這個寫法實在是太讓人驚豔了XD
{ 變數(條件) ? (
<div>
...
...
</div>
): null }
在之前寫純 HTML/CSS, JavaScript 的時候真的很難想像,
在純 JavaScript 的世界裡,
要改變文字內容我們通常會這樣寫對吧?
const element = document.getElementById('title');
if (...){
element.textContent = '這是舊標題';
} else {
element.textContent = '這是新標題';
}
或要控制它的顯示與否,
我們會這樣寫:
const element = document.getElementById('title');
if (...){
element.style.display = "block";
} else {
element.style.display = "none";
}
要先用 getElementById 拿到元件,
然後再寫 if else 判斷式,
再用 textContent 改變它的文字內容,
或寫 style.display 控制元件的顯示與否,
每次光想到要寫 getElementById 就覺得累orz
可是 React 透過這樣的方式讓人可以很直覺方便的控制網頁上的元件,
所以真的會越寫越愛 React XD
不過我覺得這一段還是必經過程啦,
這樣會更了解 DOM 的運作方式之類的,
蹲馬步還是必要的XD
這樣之後學輕功才會比較快上手XD
而且也會比較紮實XD
一樣附上今日練習:Day17 - Reactstrap (Spinners)
大家也快來玩玩看吧~~~~
今日練習一不小心玩太多XD
其實一開始只是看到 Spinners 的範例覺得長得很像奧運五環圖案,
然後就變這樣了XD"
應該明天開始就會 Codecademy 了吧(希望
那我們明天見囉!
剛才一直看到 3 秒後 Spinners 卻還在轉覺得有點煩XD
所以我小小改了 Spinners 的這段:
<div className="container px-4 mt-2">
{!isShow ? (
<>
<div className="px-2 d-flex justify-content-between">
<Spinner color="info"> </Spinner>
<Spinner color="dark"> </Spinner>
<Spinner color="danger"> </Spinner>
</div>
<div className="px-4 d-flex justify-content-around">
<Spinner color="warning"> </Spinner>
<Spinner color="success"> </Spinner>
</div>
</>
) : (
<img
alt="Olympic"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Olympic_rings_without_rims.svg/380px-Olympic_rings_without_rims.svg.png"
width="80%"
/>
)}
</div>
這意思是當 !isShow
為 true 時要顯示 Spinners,
反之只要顯示靜態圖片就好,
所以當 isShow
是 false 時會顯示 Spinners 動畫,isShow
是 true 時會顯示奧運五環的靜態圖片。
(這樣就剛好完整介紹了這個架構XD)
{ 變數(條件) ? (
<div>
...
...
</div>
): (
...
...
)}
改完後成果: