iT邦幫忙

2021 iThome 鐵人賽

DAY 16
1
自我挑戰組

Re: 從 Next.js 開始的 React 生活系列 第 16

[Day16] 學 Reactstrap 就離 React 不遠了 ~ 用 Tooltips 認識 useEffect

  • 分享至 

  • xImage
  •  

前言

昨天文章有提到在 Tooltips 看到有趣的範例,
有用到 useEffect
不過我有將範例做些微調整,
讓剛入手的人比較好理解~

本日正文

今天要介紹的就是 useEffect,
(附一下官網文件連結,但我覺得對初學者來說滿不友善的就是了XD)
這邊直接拿昨天的例子進行修改,
先給大家看以下程式碼跟它的結果:

  • 程式碼
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import React, { useState, useEffect } from "react";
import { Tooltip, Button } from "reactstrap";

export default function App() {
  const [tooltipOpen, setTooltipOpen] = useState(false);
  const toggle = () => setTooltipOpen(!tooltipOpen);

  const shortText = "夠了喔!";
  const longText = "今晚我想來點...";
  const [text, setText] = useState(shortText);
  const [isExpanded, setIsExpanded] = useState(false);

  useEffect(() => {
    if (isExpanded === true) {
      setText(longText);
    } else {
      setText(shortText);
    }
  }, [isExpanded]);

  return (
    <div>
      <p className="p-2">
        戴資穎~戴資穎~第一名!
        <br />
        戴資穎~戴資穎~我愛妳!
        <br />
        <Button
          color="link"
          id="ilovetty"
          href="#"
          className="p-0"
          onClick={() => setIsExpanded(!isExpanded)}
        >
          資穎~資穎~資穎
        </Button>
      </p>
      <Tooltip
        isOpen={tooltipOpen}
        target="ilovetty"
        toggle={toggle}
        placement="bottom"
      >
        {text}
      </Tooltip>
    </div>
  );
}
  • 結果

大家可以看到,
只要點擊「資穎~資穎~資穎」的按鈕,
Tooltip 的文字就會有所變動,
這是怎麼辦到的呢?

大家可以先看到我在按鈕的部份增加了 onClick 事件:

<Button
    ... (略)
	onClick={() => setIsExpanded(!isExpanded)}
>
  資穎~資穎~資穎
</Button>

經過兩天的洗禮,大家現在看到這個 setIsExpanded 應該不陌生了,
往上看可以看到這行的宣告:

const [isExpanded, setIsExpanded] = useState(false);

也就是說有個變數 isExpanded,初始值為 false,
setIsExpanded 是改變 isExpanded 值的方法。

所以

onClick={() => setIsExpanded(!isExpanded)}

意思是當我點擊這個按鈕,我要執行 setIsExpanded,
將 isExpanded 的值改為 isExpanded 的相反值。

再來進入本日重頭戲,
也就是我在今天範例新增的這部份:

const shortText = "夠了喔!";
const longText = "今晚我想來點...";
const [text, setText] = useState(shortText);
const [isExpanded, setIsExpanded] = useState(false);

useEffect(() => {
    if (isExpanded === true) {
      setText(longText);
    } else {
      setText(shortText);
    }
}, [isExpanded]);

useEffect 是說當組件(頁面)渲染完後,針對指定的部份偵測更新並執行。
(但我這句話可能講得不好,推薦大家可以看之前大大寫的文章 → [Day 17 - 即時天氣] 頁面載入時就去請求資料 - useEffect 的基本使用 )

先想一個情況,有時候當頁面上內容有小變動(例如數字的變化),
是不是不會馬上看到更新後的內容,
還需要按重新整理讓畫面重新渲染後才會看到更新呢?

useEffect 我覺得就像是去偵測頁面的更新,
有更新的地方就去執行並渲染在頁面上。
(並不是整個頁面的重新渲染哦,是只去偵測改變的地方並執行動作)

useEffect(() => {
    if (isExpanded === true) {
      setText(longText);
    } else {
      setText(shortText);
    }
}, [isExpanded]);

所以 , [isExpanded]); 這邊的意思是 useEffect 會去偵測 isExpanded 有沒有改變,
有改變的話我就去執行裡面的程式,
裡面這段大家應該看得懂,
就是判斷 isExpanded,true 的話就執行 setText,將 text 的值改成 longText;
反之,false 的話就執行 setText,將 text 的值改成 shortText;

可是這樣你可能會問說那 Tooltip 的文字內容為什麼會跟著改呢?
因為這邊我有做一個小變動:

<Tooltip ... (略)>
    {text}
</Tooltip>

注意到了嗎,原本在昨天的範例是「夠了喔!」的文字,
我改成了 {text}

這也是 React 方便的地方之一,
我可以用 {變數名稱} 去取得變數的值。
前面根據 isExpanded 的不同,text 就會被設定成不一樣的值,
因此這邊用 {text} 就可以去做到這樣的變化。
很好玩吧!

最後再為大家整理一下今天這個範例的幾個重點:

  1. <Tooltip> 的文字內容改為 {text}
  2. <Button> 新增 onClick 事件,去改變 isExpanded 的值
  3. 新增 useEffect 去偵測 isExpanded 的變化,
    根據 isExpanded 的不同,text 就會被設定成不一樣的值

這樣就可以做到點擊後改變 Tooltip 的文字內容了。

是不是感受到 useEffect 的有趣之處了?
附上本日範例:Day16 - Reactstrap (Tooltips)
大家也可以自己試著玩玩看哦!

後記

我突然翻到在 Codecademy 上面有 React 的教學!
https://www.codecademy.com/learn/react-101

Codecademy 裡面有各種程式的教學,
如 HTML & CSS, Python, JavaScript..... 等,
過程是把學習步驟拆成一步一步,
每一步都有附上說明,還有小練習,
所以你可以自己慢慢學習~

我之前在 Codecademy 學過 HTML, jQuery,
沒想到 Codecademy 連學習證書都有,跟 Udemy 好像XD
這邊附一下我當初的學習證書XD
https://ithelp.ithome.com.tw/upload/images/20210918/201298731BA11QeYFn.png

沒想到現在連 React 教學都有了!
決定接下來要在 Codecademy 加(ㄜˋ)強(ㄅㄨˇ)我的 React 基礎,
也會同步在文章 po 出我的學習過程,
那我們明天見啦!


上一篇
[Day15] 學 Reactstrap 就離 React 不遠了 ~ 用 Tooltips 熟悉 useState
下一篇
[Day17] 學 Reactstrap 就離 React 不遠了 ~ 用 Spinners 搭配複習 Flex, useState, useEffect 三個願望一次滿足!
系列文
Re: 從 Next.js 開始的 React 生活31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言