iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Modern Web

連我阿公都會-手把手教你架網站 系列 第 24

【Day24】淺談 React.js(3)React useState & useEffect

  • 分享至 

  • xImage
  •  

介紹完React的動態生成後,本篇將帶您進入到React Hook的領域。

甚麼是React hook?簡單來說,它是一種React的函數,可以讓您在無需使用class(類別)語法的情況下,便能使用state(狀態)和其他React功能。雖說它可以取代class,但它也可以同class一起共存,在了解完畢後,您便依照您的喜好去操作即可。更詳細的便不做介紹了,若您感興趣的話,不妨至React官網查看 ⇒ https://zh-hant.legacy.reactjs.org/docs/hooks-intro.html

而React Hook中,最常見的是useState和useEffect。以下是它們的基本介紹:

  • useState:此Hook允許您為函數元件中添加狀態。您可以使用它來儲存和更新元件的狀態變數,而不需要類別語法。如:您可以使用useState來追蹤一個計數器的數值。其實useState 就像是 class 中 this.state 的功能。但是,在一般情況下,變數會在function 結束時「消失」,但 state 變數會被 React 保留起來。
  • useEffect:此Hook用於處理side effects,如:獲取數據、訂閱事件…等功能。您可以在useEffect中定義操作,並指定何時執行它們,通常是在元件渲染後或特定狀態更改後。使用useEffect函式,React便會記住您所傳遞的function(即effect),並在執行DOM更新後,呼叫它。

React Hook的優勢在於它們使元件邏輯更容易共享和重用,並且可以簡化代碼。除了useState和useEffect,還有其他許多Hooks,如useContext、useReducer等,它們可以滿足不同的需求,使React應用程式的開發更具效率和可維護性,老話一句,若您感興趣的話,不妨上網自行查詢並鑽研喔!

簡單的useState範例:


這裡我們創建一個簡單的頁面:
https://ithelp.ithome.com.tw/upload/images/20231009/20160488tYcRtKSiGI.png

我們要製作一個計數器:

// Count.js
const Count = () => {
    const btnStyle = {
        "marginTop": "5%",
        "padding": "1.5% 3%",
        "borderRadius": "20px",
        "backgroundColor": "rgb(232, 232, 232)"
    }

    return (
        <center>
            <button style={btnStyle}>count:0</button>
        </center>
    )
}

export default Count;

https://ithelp.ithome.com.tw/upload/images/20231009/20160488MaDOodJt3t.png

接著,我們要做到,點擊按鈕時,裡面的數字便+1的效果。

此時我們最直觀的想法可能是這樣的:

建立一個count的變數,用以存放點擊的值,而後在點擊按鈕的時候+1:

const Count = () => {
    const btnStyle = {
        "marginTop": "5%",
        "padding": "1.5% 3%",
        "borderRadius": "20px",
        "backgroundColor": "rgb(232, 232, 232)"
    }

    let count = 0;
    const click = () => {
        count++;
    }

    return (
        <center>
            <button style={btnStyle} onClick={click}>count:{count}</button>
        </center>
    )
}

export default Count;

我們可以修改click函式:

const click = () => {
    count++;
    console.log(count);
}

可以發現count的值是有發生變化的,但是 ── 畫面並沒有做渲染呢。
https://ithelp.ithome.com.tw/upload/images/20231009/20160488kcKmWcenQr.png

因此,這裡我們就需要使用到 useState() 來達成我們的效果。

使用 useState()

const [變數,設定變數的函式] = useState(預設值);

建立count的state:

const [count,setCount] = useState(0);

建立 click() 函式:

const [count,setCount] = useState(0);
const click = () => {
    setCount( (prev) => {
        return prev+1;
    })
}

完整code:

import { useState } from "react";

const Count = () => {
    const btnStyle = {
        "marginTop": "5%",
        "padding": "1.5% 3%",
        "borderRadius": "20px",
        "backgroundColor": "rgb(232, 232, 232)"
    }

    const [count,setCount] = useState(0);
    const click = () => {
        setCount( (prev) => {
            return prev+1;
        })
    }
    
    return (
        <center>
            <button style={btnStyle} onClick={click}>count:{count}</button>
        </center>
    )
}

export default Count;

看到這段code,我們可以發現一個問題,為什麼不直接使用setCount跟count去做加減,而是再寫了一個箭頭函式,得到現在的值後,再進行+1呢?

這樣寫的主要原因,是為了確保在更新計數器時使用了先前的值 :prev,而不是直接使用當前的值。因為JavaScript中的狀態更新可能是非同步的,如果多個事件同時觸發,可能會導致競態條件(即兩個訊號試著彼此競爭,來影響誰先輸出)。

透過使用 (prev) => { return prev + 1; } 這樣的方式,可以確保在更新計數器時使用了先前的值,而不受其他事件的干擾。這是 React 中處理狀態更新的一個常見做法,特別是當狀態更新依賴於先前的狀態值時,這樣的寫法更為安全和可靠。

所以我們不希望透過直接改變count的值,而是希望透過setCount的函數去改變count的值。

這樣子計數器就完成了!是不是超級簡單呢?
https://ithelp.ithome.com.tw/upload/images/20231009/20160488GRo4NCpXeN.png

簡單的useEffect範例:


useEffect跟uesState非常相像,useEffect的使用通常用於元件的狀態發生改變時,所發生的改變上。

以下是useEffect最基本的語法:

useEffect(() => {
	要執行的操作
},[訂閱變數])

接續上面的計數器範例,讓我們加入幾行code:

import { useState } from "react";
import { useEffect } from "react";

const Count = () => {
    const btnStyle = {
        "marginTop": "5%",
        "padding": "1.5% 3%",
        "borderRadius": "20px",
        "backgroundColor": "rgb(232, 232, 232)"
    }

    const [count,setCount] = useState(0);
    const click = () => {
        setCount( (prev) => {
            console.log("count++");
            return prev+1;
        })
    }

    useEffect(() => {
        console.log("甚麼!!count發生改變了,現在的值是"+count);
    },[count])

    return (
        <center>
            <button style={btnStyle} onClick={click}>count:{count}</button>
        </center>
    )
}

export default Count;

可以發現,每當我們點擊了count,就會執行一次useEffect內的內容。

不過,值得注意的是為什麼進到網站後,useEffect被執行了兩次?

useEffect 被執行兩次是因為,一次是在初始渲染時,另一次是在 count 狀態變化時(設定值為0)。
https://ithelp.ithome.com.tw/upload/images/20231009/20160488QRkfdRd32n.png

useEffect擁有在網頁全部的渲染前執行的特性,我們可以藉此運用發揮,在 useEffect()內塞一些初始化的東西或入場動畫。

useEffect(()=>{
    console.log("初始化");
},[])

useEffect和useState的基本教學就到這邊囉。
本日的React hook ── useState和useEffect便介紹到這裡,明天我們將介紹React共同元素該怎麼做,那我們明天見囉!


上一篇
【Day23】淺談 React.js(2)React動態生成
下一篇
【Day25】淺談 React.js(4)公共元件 & 頁面跳轉 Router
系列文
連我阿公都會-手把手教你架網站 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言