Day 8【钱包登入区 - Loading Message】阿嬷为什麽你有感觉?

【前言】
一样先来回顾一下 Day2 Project 分析的使用者流程,今天来做第二步的**「验证帐号读取时的 Loading 特效」**。我发现写 React 的心路历程跟这个广告很像,一下子在想为什麽没感觉,一下子又在想为什麽你有感觉。很多东西到底怎麽出现的自己也不是很了解哈哈哈哈哈哈哈哈哈哈。

【(使用者看见的)前端与(後方运作的)後端】

  1. 使用者会看见登入钱包按钮(按钮应该要有一些特效)
    • 按下按钮後要连到 MetaMask 系统
  2. 使用者点击按钮後出现 Loading 特效,同时跳出 Metamask 登入及连动同意
    • 同意後,要从 MetaMask 得到当前登入者的以太坊地址
  3. 使用者同意後出现登入介面,让其输入欲登入的角色编号
    • 得到欲登入的角色编号後,去後方资料库查询此地址是否真的拥有此 NFT
      // 资料库建构的部分由其他夥伴负责,这边我负责检查 Tokens 的持有地址
  4. 成功登入後的画面
    // 网页互动的部分由其他夥伴负责,这边我负责显示登入成功 or 失败

【Loading Message】
利用到 Day 6 学到的 setIsPending() 来输出 Loading Message。目前我的设想是:在使用者点下登入按钮之後,跳出 MetaMask 的 API,到系统後端确认登入的这段时间,页面都要呈现 Loading Message 或相关特效。

首先在 index.jsx import useEffect()useState()

import { useEffect, useState } from "react";

再来在 function return 之前加上 useState() 的叙述。

export function AccountBox(props) {
  ...
  const [isPending, setIsPending] = useState(true);
	...
  return (
    <AccountContext.Provider value={contextValue}>
      ...
		</AccountContext.Provider>
  );
}

useState() 的宣告以及return 之间加入 useEffect() 来随时随地侦测是否需要产出 Loading Message。附带一提,这边当然是为了让 Loading 的效果出现才会特别用 setTimeout() 哈哈哈哈哈哈哈哈。因为我还没有架设 json 的服务器来供利用所以可以先忽略 fetch 的部分。

useEffect(() => {
  setTimeout(() => {
    fetch('...')
    .then(res => {
      return res.json();
    })
    .then(data => {
      setIsPending(false);
    })
  }, 1000);
}, [])

目前的结果呈现是这样,但跟我想像中的不一样,应该要只出现 Loading Message,Loading 结束之後才出现登入介面才对! 後来才知道是我应该增加一个 bool 来选择在 Loading 时先不要出现 <BoxContainer> ... </BoxContainer> 的资讯内容,等 Loading 结束後 isPending() == false 才会输出登入介面。

export function AccountBox(props) {
  ...
  const [isPending, setIsPending] = useState(true);
	...
	useEffect(() => {
    setTimeout(() => {
      setIsPending(false);
    }, 1000);
  }, [])
	...
  return (
    <AccountContext.Provider value={contextValue}>
      { active === "signin" && (
        <LoginWrapper>
          { isPending && <div>Loading...</div> }
          <BoxContainer>
						...
					</BoxContainer>
        </LoginWrapper>
      )}
    </AccountContext.Provider>
  );
}

原本以为这个过程很简单,没想到在 useEffect() 上的 BUG 一堆,Loading Message 在 return 里面的位置也需要思考一下。经过精简再精简的排除之後完整的程序码大概长这样!之後会把 json 的利用加回来,希望大家好好期待,这里先着重在 Loading Message 的呈现。

export function AccountBox(props) {
  ...
  const [isPending, setIsPending] = useState(true);
	...
	useEffect(() => {
    setTimeout(() => {
      setIsPending(false);
    }, 1000);
  }, [])
	...
  return (
    <AccountContext.Provider value={contextValue}>
      <LoginWrapper>
        { isPending && <div>Loading...</div> }
				{ !isPending && 
					<BoxContainer>
						...
					</BoxContainer>
				}
      </LoginWrapper>
    </AccountContext.Provider>
  );
}

【Loading Effect】
现在要开始对 Loading Message 加入特效,主要就是对 <div>Loading...</div> 这块进行变化!如果只有使用 div 输出文字的话是长这样:(非常阳春)

经过在网路上多方寻找之後,我发现了一个非常棒的东西很符合需求,使用起来也没有那麽复杂!首先来到以下这个网站找一个自己喜欢的 Loading 图样,然後调整自己喜欢的颜色、速度、尺寸。

React Spinners

然後在Command Line 执行以下程序:

npm install --save react-spinners

并且在 index.jsx 之中引入套件。其中 "~" 的部分为自己想要的 Loading 图样的名称,我选择的是 RingLoader,范例如下:

import ~ from "react-spinners/~";

e.g.
import RingLoader from "react-spinners/RingLoader";

这边我使用的 Loading 特效及程序码是这样,因为发现可以覆写 CSS 所以我对他做一点改变。

{ isPending && 
	<RingLoader 
		size={170} 
		color={"#36D7B7"} 
		loading={isPending} 
		speedMultiplier={1.05} 
		css={override} />
}

记得在覆写 CSS 之前要先 import emotion

import { css } from "@emotion/react";

const override = css`
  display: block;
  margin: 112% auto;
  overflow:hidden;
`;

呈现的结果非常不错!

原本我直接把程序码丢进去 return 的时候想说今天的内容也未免太简单了,结果 compiler error 了好久,他一直告诉我 "loading" 没有宣告过,後来才发现原来我是使用 isPending 来当作是否在 Loading 的 bool。

【小结】
React 让我有一种又惊又喜又怕,既期待又怕受伤害的感觉,每次看到很棒的特效或者前端的时候都会想实作看看,但每次元件的复杂程度还有未知的 BUG 都会一次次的打击信心。不过我会继续加油的,毕竟跟一开始完全对前端毫无涉猎的我相比,现在已经进步很多了吧!

【参考资料】
react-spinners
CSS overflow 属性用法


<<:  Day6 Python基础语法四

>>:  [从0到1] C#小乳牛 练成基础程序逻辑 Day 5 - 资料类型 $字串插补

滥用案例(misuse cases)

-用例和滥用案例(来源:https://en.wikipedia.org/wiki/Misuse_...

高防CDN如何防御日益迭代的网络攻击?

随着互联网的日新月异,人们对於服务器租用要求也是越来越高,其中高防CDN就是受到大家关注的一种服务类...

Day22:Hot Flow - SharedFlow (Part II)

昨天我们使用了 shareIn 将 Flow 转成 SharedFlow, 我们来研究一下这个函式。...

[Day30]Flutter Netflix UI 使用shared_preferences

大家好,今天是最後一天,今天跟大家介绍shared_preferences,可以把一些简单的设定的东...

[重构倒数第28天] - 关於拆分 Components 的学问

前言 该系列是为了让看过Vue官方文件或学过Vue但是却不知道怎麽下手去重构现在有的网站而去规画的系...