iT邦幫忙

2022 iThome 鐵人賽

DAY 13
5
Software Development

React框架白話文運動系列 第 13

React白話文運動13-React Hook-useState 02

  • 分享至 

  • xImage
  •  

前言

嗨,我是Hogan
目前在經營自己的自媒體 hogan.tech
主要分享一些有關於程式碼、軟體和科技業經驗分享
有興趣的讀者可以進一步關注我,進而獲得更多資訊唷!

未來文章一併更新於此網站 Hogan.B Lab
並且包含多語系 繁體中文英文日文簡體中文
觀看分類:React 白話文運動其他系列

如果想要快速查找其他文章請點選目錄

成立 hogan.tech 的初衷是
希望每個正在這條路上探索的人,
都可以透過 Hogan.tech 嘗試進入程式領域。


前一篇講解用實例來解說hook中的useState,包含:

  1. 建立一個評價的UI元件
  2. 針對此元件進行重構
  3. 為此元件加上useState 的hook

這一篇則會繼續講解useState,以及提供舊版程式碼供比對

  1. 新增setState為評價元件新增修改功能
  2. 舊版的React狀態管理寫法

複習

這一篇先來複習一下前一篇的程式碼,完成了一個評價的UI元件。

首先有一個大元件叫做 <StarRating />,內容包含了文字以及小型的星星元件。

也另外針對 selectedStars 這個變數,使用useState 新增預設值。

export function StarRating({ totalStars = 5 }) {
    const [selectedStars] = useState(3)
    return <div>
        {createArray(totalStars).map((n, i) => <Star key={i} selected={selectedStars > i} />)}
        <p>
            {selectedStars} of {totalStars} stars
        </p>
    </div>
}

接著有一個小元件叫做 <Star />,星星元件本身可以代selected參數,如果是true則會顯示紅色,則顯示灰色。

const Star = ({ selected = true }) => (
    <FaStar color={selected ? 'red' : 'gray'}></FaStar>
)

接下來另外宣告了一個函式createArray( ) ,只要給予了一個長度,就會自動建立一個對應長度的空陣列。

const createArray = length => [...Array(length)];

全部可執行的程式碼如下:

import React from 'react'
import { useState } from 'react';
import { FaStar } from 'react-icons/fa'

const Star = ({ selected = true }) => (
    <FaStar color={selected ? 'red' : 'gray'}></FaStar>
)

const createArray = length => [...Array(length)];

export function StarRating({ totalStars = 5 }) {
    const [selectedStars] = useState(3)
    return <div>
        {createArray(totalStars).map((n, i) => <Star key={i} selected={selectedStars > i} />)}
        <p>
            {selectedStars} of {totalStars} stars
        </p>
    </div>
}

新增setState為評價元件新增修改功能

useState( ) 除了可以給予預設值以外,也可以修改其值,這邊可以使用 setState來去做修改

以下可以在StarRating 中,新增一個 setSelectedStars,就可以在元件中做使用

這邊也在Star 裡面新增一個函數引數,稱為onSelect ,並且將setSelectedStars 傳進去

export function StarRating({ totalStars = 5 }) {
    const [selectedStars, setSelectedStars] = useState(3)
    return <div>
       {createArray(totalStars).map((n, i) => 
		<Star 
    		key={i} 
    		selected={selectedStars > i} 
    		onSelect={() => setSelectedStars(i + 1)} />
		)}
        <p>
            {selectedStars} of {totalStars} stars
        </p>
    </div>
}

這邊再將傳進來的函數引數setSelectedStars ,傳入onClick 的函數中

則所有的星星元件點擊之後,都會觸發 setSelectedStars( )

const Star = ({ selected = true, onSelect = f => f }) => (
    <FaStar color={selected ? 'red' : 'gray'} onCLick={onSelect}></FaStar>
)

這邊也附上完整的useState 程式碼

import React from 'react'
import { useState } from 'react';
import { FaStar } from 'react-icons/fa'

const Star = ({ selected = true, onSelect = f => f }) => (
    <FaStar color={selected ? 'red' : 'gray'} onCLick={onSelect}></FaStar>
)

const createArray = length => [...Array(length)];

export function StarRating({ totalStars = 5 }) {
    const [selectedStars, setSelectedStars] = useState(3)
    return <div>
        {createArray(totalStars).map((n, i) => 
		<Star 
    		key={i} 
    		selected={selectedStars > i} 
    		onSelect={() => setSelectedStars(i + 1)} />
		)}
        <p>
            {selectedStars} of {totalStars} stars
        </p>
    </div>
}

舊版的React狀態管理寫法

舊版是指比較早期的類別元件寫法,因為hook只能用於函式元件

這邊則是展示類別元件的狀態管理,不過因為類別元件本身有一些物件導向的概念,會比較難理解

相較於useState 去做資料狀態的預設以及更新,類別元件中使用的是建構子(constructor)

建構子可以給予 starSelected 的預設值為0,並且也另外針對類別中宣告的函式change進行綁定

最後再透過render( ) 函式去做元件的渲染

import React, { Component } from 'react'
import { FaStar } from 'react-icons/fa'


const Star = ({ selected = true }) => (
    <FaStar color={selected ? 'red' : 'gray'}></FaStar>
)

const createArray = length => [...Array(length)];


export default class StarRating extends Component {
    constructor(props) {
        super(props);
        this.state = {
            starSelected: 0
        };
        this.change = this.change.bind(this);
    }

    change(starSelected){
        this.setState({starSelected});
    }

    render(){
        const {totalStars} = this.props;
        const {starSelected} = this.state;
        return (
            <div>
                {[...Array(totalStars)].map((n,i)=>{
                    <Star 
                        key={i} 
                        selected={i < starSelected} 
                        onClick={()=>this.change(i+1)}
                    />
                })}
                <p>
                    {starSelected} of {totalStars} stars
                </p>
            </div>
        )
    }
}

結語

連續兩篇使用程式碼講解React useState,也有另外針對早期的寫法,進行對比。

如果有任何建議與疑問也歡迎留言!

如果喜歡此系列文章,請不吝於按下喜歡及分享,讓更多人看到唷~


上一篇
React白話文運動12-React Hook-useState 01
下一篇
React白話文運動14-React Hook-useEffect 01
系列文
React框架白話文運動30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言