溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

React函數(shù)式組件與類組件的不同點(diǎn)是什么

發(fā)布時(shí)間:2022-03-29 15:28:07 來(lái)源:億速云 閱讀:311 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“React函數(shù)式組件與類組件的不同點(diǎn)是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“React函數(shù)式組件與類組件的不同點(diǎn)是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

區(qū)別

區(qū)別函數(shù)組件類組件
生命周期無(wú)
this無(wú)
state無(wú)
改變stateReact Hooks:useStatethis.setState()
性能高(不用實(shí)例化)低(需要實(shí)例化)

其他區(qū)別

ProfilePageClass.js

import React from 'react';

class ProfilePageClass extends React.Component {
    showMessage = () => {
        alert('Folloed' + this.props.user);
    };

    handleclick = () => {
        setTimeout(this.showMessage,3000);
    };

    render(){
        return <button onClick={this.handleclick}>Follow</button>
    }
}

export default ProfilePageClass;

ProfilePageFunction.js

import React from 'react';

function ProfilePageFunction(props){
    const showMessage = () => {
        alert('Followed'+ props.user);
    }

    const handleClick = () => {
        setTimeout(showMessage,3000);
    }

    return(
        <button onClick={handleClick}>Follow</button>
    )
}


export default ProfilePageFunction;

Home.js

import React from "react";

import ProfilePageFunction from './ProfilePageFunction';
import ProfilePageClass from './ProfilePageClass';

class Home extends React.Component {
    state = {
        user: 'Dan',
    };
    render() {
        return (
            <>
                <label>
                    <b>Choose profile to view: </b>
                    <select
                        value={this.state.user}
                        onChange={e => this.setState({ user: e.target.value })}
                    >
                        <option value="Dan">Dan</option>
                        <option value="Sophie">Sophie</option>
                        <option value="Sunil">Sunil</option>
                    </select>
                </label>
                <h2>Welcome to {this.state.user}'s profile!</h2>
                <p>
                    <ProfilePageFunction user={this.state.user} />
                    <b> (function組件)</b>
                </p>
                <p>
                    <ProfilePageClass user={this.state.user} />
                    <b> (class組件)</b>
                </p>
                <p>
                    Can you spot the difference in the behavior?
                </p>
            </>
        )
    }
}

export default Home;

頁(yè)面展示:

React函數(shù)式組件與類組件的不同點(diǎn)是什么

進(jìn)行如下操作發(fā)現(xiàn)問(wèn)題:(初始用戶為Dan)

1.點(diǎn)擊其中的Follow按鈕

2.3s內(nèi)切換選中的賬號(hào)

3.查看彈出的文本。

點(diǎn)擊函數(shù)組件的Follow:

React函數(shù)式組件與類組件的不同點(diǎn)是什么

點(diǎn)擊類組件的Follow:

React函數(shù)式組件與類組件的不同點(diǎn)是什么

點(diǎn)擊件的Follow按鈕時(shí),執(zhí)行handleClick(),3s后顯示用戶的姓名。

函數(shù)組件:若你在點(diǎn)擊Follow按鈕3s內(nèi)切換用戶,3s后調(diào)用的函數(shù)輸出的用戶仍未之前的用戶姓名。

類組件:若你在點(diǎn)擊Follow按鈕3s內(nèi)切換用戶,3s后調(diào)用的函數(shù)輸出的用戶為改變之后的用戶姓名。

此時(shí)類組件就有一個(gè)問(wèn)題:我之前的handleClick()執(zhí)行的是A用戶的操作,但操作還沒(méi)執(zhí)行,切換用戶后,直接調(diào)用執(zhí)行了B用戶的相同操作。

此案例中,當(dāng)父組件的state改變時(shí),子組件進(jìn)行重新渲染,子組件的props改變;

類組件:

  • 改變props(Dan-Sophie),類組件也改變了值,永遠(yuǎn)保持一致。

  • 原因:類組件捕獲最新的值(永遠(yuǎn)保持一致)當(dāng)實(shí)例的props屬性發(fā)生修改時(shí),class組件直接使用this(組件的實(shí)例),所以可以直接獲取組件最新的props。

函數(shù)組件:函數(shù)式組件捕獲了渲染所用的值。

  • 當(dāng)我改變props時(shí)(Dan->Sophie),你會(huì)發(fā)現(xiàn)函數(shù)組件會(huì)渲染之前的值Dan這個(gè)名字。

  • 原因:函數(shù)式組件捕獲了渲染所使用的值。在函數(shù)組件中,之前的props參數(shù),已經(jīng)因?yàn)閖avascript閉包的特性,保存在內(nèi)存之中,無(wú)法從外部進(jìn)行修改(維護(hù)多個(gè)人的狀態(tài))。所以在定時(shí)器執(zhí)行callback時(shí),打印的還是舊值。

使用Hooks,同樣的原則也適用于state??催@個(gè)例子:

MessageThread.js

import {useState} from 'react';

function MessageThread() {
    const [message, setMessage] = useState('');

    const showMessage = () => {
        alert('You said: ' + message);
    };

    const handleSendClick = () => {
        setTimeout(showMessage, 3000);
    };

    const handleMessageChange = (e) => {
        setMessage(e.target.value);
    };

    return (
        <>
            <input value={message} onChange={handleMessageChange} />
            <button onClick={handleSendClick}>Send</button>
        </>
    );
}

export default MessageThread;

React函數(shù)式組件與類組件的不同點(diǎn)是什么

說(shuō)明了同樣的觀點(diǎn):如果我發(fā)送一條特定的消息,組件不應(yīng)該對(duì)實(shí)際發(fā)送的是哪條消息感到困惑。這個(gè)函數(shù)組件的message變量捕獲了“屬于”返回了被瀏覽器調(diào)用的單擊處理函數(shù)的那一次渲染。

所以當(dāng)我點(diǎn)擊“發(fā)送”時(shí)message被設(shè)置為那一刻在input中輸入的內(nèi)容。

在函數(shù)式組件中,你也可以擁有一個(gè)在所有的組件渲染幀中共享的可變變量,它被成為“ref”。 ref可以隨時(shí)讀取當(dāng)前值。
需要自己手動(dòng)管理。

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

function MessageThread() {
    const [message, setMessage] = useState('');

    // Keep track of the latest value.
    const latestMessage = useRef('');
    useEffect(() => {
        latestMessage.current = message;
    });
    

    const showMessage = () => {
        alert('You said: ' + latestMessage.current);
    };

    const handleSendClick = () => {
        setTimeout(showMessage, 3000);
    };

    const handleMessageChange = (e) => {
        setMessage(e.target.value);
    };

    return (
        <>
            <input value={message} onChange={handleMessageChange} />
            <button onClick={handleSendClick}>Send</button>
        </>
    );
}

export default MessageThread;

React函數(shù)式組件與類組件的不同點(diǎn)是什么

讀到這里,這篇“React函數(shù)式組件與類組件的不同點(diǎn)是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI