[Day17] 学 Reactstrap 就离 React 不远了 ~ 用 Spinners 搭配复习 Flex, useState, useEffect 三个愿望一次满足!

前言

虽然昨天的文章有提到我想在 Codecademy 开始打 React 的基础,
不过看前几天我的文章顺序是 认识 useState、熟悉 useState、认识 useEffect
所以今天应该要排一个熟悉 useEffect XD
而刚好看到一个我之前没注意到的 component,
所以就顺便来个综合练习吧~~~

本日正文

用 Flex 排出奥运五环图案

今天要为大家介绍的 component 是 Spinners
看到这样的色系不觉得会让人联想到奥运的五环图案吗XD
所以我今天想要用 Spinners 来弄奥运的图示XD
https://ithelp.ithome.com.tw/upload/images/20210919/20129873RNvkWO7YZF.png

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>

https://ithelp.ithome.com.tw/upload/images/20210919/20129873XGfFxWVWFh.png

所以我只好把范例改写成这样:

<div>
  <Spinner color="info">{' '}</Spinner>
  <Spinner color="dark">{' '}</Spinner>
  <Spinner color="danger">{' '}</Spinner>
  <Spinner color="warning">{' '}</Spinner>
  <Spinner color="success">{' '}</Spinner>
</div>

https://ithelp.ithome.com.tw/upload/images/20210919/20129873HJ2a701INS.png

参考奥运五环图案,

所以挑了 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>

https://ithelp.ithome.com.tw/upload/images/20210919/20129873WVKCe7efj0.png

用 useEffect & setTimeout 弄出时间差显示

到这边排版的部份就告一段落,
再来就是为了也要练习 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>
    </>
  );
}

https://ithelp.ithome.com.tw/upload/images/20210919/20129873sIZGNCSyjj.png

再来思考一下这样该怎麽做:

倒数 3 秒後才会显示下方的奥运佳绩榜

相信大家对 setTimeout 并不陌生,
setTimeout 就是可以设定几秒後执行 function,
(setInterval 则是设定每几秒就执行一次 function)
因此像这样的 setTimeout 这样的 function,
也是 useEffect 的服务范围,
就是当页面(组件)渲染後且会有变化就要执行,
所以我们先在 useEffect 写上 setTimeout:

useEffect(() => {
    setTimeout(() => {

    }, 3000);
});

(3000 就是 3 秒後要执行里面 function 的意思)

想一下我们 3 秒後要执行的动作:

  1. 「载入中......」文字变成「2金-4银-6铜」
  2. 奥运佳绩榜从不显示到显示出来

所以前面先这样宣告:

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>
): (
    ...
    ...
)}

改完後成果:


<<:  Day04-Vue指令

>>:  [Day19]乖离率网格实作

家齐高中资讯研究社 社课内容2

基本建置 1.discord 开发者介面里点取newapplication 2.在Bot上点取Add...

[Day_29]函式与递回_(8)

函式视为物件 Python中函式视为物件,以函式名称当作物件,函式名称加上()才会执行该函式,范例如...

DAY 13- 《公钥密码》-RSA(1)

第一个要来看的公钥加密演算法是 RSA。 记得我们在 DAY6 的时候介绍到 RC4 时提到一个人吗...

萤幕录影和笔电录音-- Windows 7/8

新版本的 Windows 作业系统,但是不少用户还是喜欢用经典的 Windows 7/8 版本。我们...

DAY 01 前言

前言 第一次参加铁人赛,真是有点小紧张哎嘿,虽然自己平常也是有在写一些技术文件,但是三十天连载这种大...