国产睡熟迷奷白丝护士系列精品,中文色字幕网站,免费h网站在线观看的,亚洲开心激情在线

      <sup id="hb9fh"></sup>
          1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

            手機(jī)站
            千鋒教育

            千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

            千鋒教育

            掃一掃進(jìn)入千鋒手機(jī)站

            領(lǐng)取全套視頻
            千鋒教育

            關(guān)注千鋒學(xué)習(xí)站小程序
            隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

            當(dāng)前位置:首頁  >  技術(shù)干貨  > 為什么react選擇了函數(shù)式組件(剖析原理)

            為什么react選擇了函數(shù)式組件(剖析原理)

            來源:千鋒教育
            發(fā)布人:wjy
            時(shí)間: 2022-06-06 11:54:00 1654487640

            以下代碼,沒有使用模塊化的方式,使用的是CDN的方式。如果需要源代碼,請(qǐng)從這個(gè)地址下載:

            ```text
            鏈接:https://pan.baidu.com/s/1s57mr5AE_ecWBFZ5TJTwqw  提取碼:f7x2
            ```

            另外,這篇文章,主要是剖析**組件的初次渲染和重新渲染**。所以,其它部分不要太較勁。

            為什么react選擇了函數(shù)式組件

            ### **一、react類組件和函數(shù)式組件重新渲染時(shí)的區(qū)別**

            ### **1、看現(xiàn)象:**

            ### **1)代碼(demo01)**

            **類組件:**

            ```js
                // 1、類組件
                class ComClass extends React.Component {
                    constructor(props) {
                        super();
                        this.props = props;
                        console.log("類組件的構(gòu)造函數(shù)被調(diào)用了");
                    }

                    render() {
                        console.log("類組件的render被調(diào)用了");
                        return (
                        <div style={{ "backgroundColor": "pink" }}>
                                <h5 >我是類組件</h5>
                                <p>{this.props.name}</p>
                            </div>
                        );
                    }
                }
            ```

            **函數(shù)式組件:**

            ```js
                 // 2、函數(shù)式組件
                function ComFn(props) {
                    console.log("函數(shù)式組件的函數(shù)被調(diào)用了");
                    return (               
                        <div style={{ "backgroundColor": "skyblue" }}>
                            <h5 >我是函數(shù)式組件</h5>
                            <p>{props.name}</p>
                        </div>
                    );
                }

            ```

             

            **使用組件:**

            ```js

                let name = "張三瘋";
                function changeName() {
                    name = "張四瘋"
                    renderDom();
                }

                function renderDom() {
                    ReactDOM.render(
                        <div>
                            <button onClick={changeName} >修改</button>
                            <ComClass name={name} /><br />
                            <ComFn name={name} />
                        </div>, document.getElementById("box"));
                }

                renderDom();

            ```

             

            ### **2)運(yùn)行:**

            2.1)初次運(yùn)行時(shí),我們發(fā)現(xiàn)在控制臺(tái)中打印的內(nèi)容為:

            ```js
            類組件的構(gòu)造函數(shù)被調(diào)用了
            類組件的render被調(diào)用了
            函數(shù)式組件的函數(shù)被調(diào)用了
            ```

             

            2.2)當(dāng)點(diǎn)擊“修改”按鈕時(shí),我們發(fā)現(xiàn)控制臺(tái)中打印的內(nèi)容為:

            ```js
            類組件的render被調(diào)用了
            函數(shù)式組件的函數(shù)被調(diào)用了
            ```

             

            ### **3)總結(jié)(敲黑板,重點(diǎn)):**

            1、類組件重新渲染時(shí),只調(diào)用了render

            2、函數(shù)式組件重新渲染時(shí),會(huì)調(diào)用函數(shù)整個(gè)本身(哈哈,不調(diào)用它也不行啊)

             

            ### **2、看原理:**

            ### **1)用原生的方式剖析:**

            函數(shù)式組件的剖析:

            ```js
            標(biāo)簽的方式使用函數(shù)式組件:
            <ComFn name={name} />
            基本上等價(jià)于:
            {ComFn({name})} //組件的方式使用,就是在調(diào)用函數(shù)
            ```

            類組件的剖析:

            ```js
            標(biāo)簽的方式使用類組件:
            <ComClass name={name} /><br/>
            等價(jià)于
            {new ComClass({name}).render()}

            但是
            這樣改了后,初次渲染沒有問題。當(dāng)點(diǎn)擊了“修改”按鈕時(shí),不一樣了。
            所以,類組件里,應(yīng)該是把new ComClass({name})實(shí)例化出來的對(duì)象,記錄起來了。所以,應(yīng)該等價(jià)于
            1、定義一個(gè)對(duì)象,保存了new ComClass({name})
               //在react里對(duì)類組件對(duì)象進(jìn)行了保存。
               let comObj = new {new ComClass({name});

            2、在渲染時(shí),只是調(diào)用了類組件的render函數(shù)。
               comObj.render();
            ```

            即:最終代碼變成了如下:

            ### **2)代碼(demo02):**

            類組件和函數(shù)式組件的代碼不用改變。

            **使用組件**

            ```js
                let name  = "張三瘋";
                //此處保存了類組件的實(shí)例化對(duì)象(這個(gè)只是模擬實(shí)現(xiàn),react內(nèi)部并不是這么簡單)
                let comObj = new ComClass({name});
                function changeName(){
                    name = "張四瘋";
                    comObj.props = {name}
                    renderDom();
                }

                function renderDom(){
                    ReactDOM.render(
                    <div>
                        <button onClick={changeName} >修改數(shù)據(jù)</button>
                        {/*此處用原生的方式使用組件*/}
                        {comObj.render()}
                        {ComFn({name})}
                    </div>, document.getElementById("box"));
                }

                renderDom();
            ```

            ### **3)運(yùn)行:**

            3.1)、初次運(yùn)行時(shí),我們發(fā)現(xiàn)在控制臺(tái)中打印的內(nèi)容為:

            ```js
            類組件的構(gòu)造函數(shù)被調(diào)用了
            類組件的render被調(diào)用了
            函數(shù)式組件的函數(shù)被調(diào)用了
            ```

            3.2)、當(dāng)點(diǎn)擊“修改”按鈕時(shí),我們發(fā)現(xiàn)控制臺(tái)中打印的內(nèi)容為:

            ```js
            類組件的render被調(diào)用了
            函數(shù)式組件的函數(shù)被調(diào)用了
            ```

             

            > 運(yùn)行結(jié)果和組件的方式一樣。

            ### **二、看看組件里使用定時(shí)器,并且,重新渲染組件**

            ### **1、看現(xiàn)象**

            ### **1)代碼(demo03):**

            **類組件:**

            ```js
               // 1、類組件
                class ComClass extends React.Component {
                    constructor(props) {
                        super();
                        this.props = props;
                        console.log("類組件的構(gòu)造函數(shù)被調(diào)用了");
                    }

                    showMessage = () => {
                        //在顯示props時(shí)(通過this訪問props),props里的內(nèi)容被改變了。
                        console.log('類組件: ' + this.props.name);
                    };

                    handleClick = () => {
                        // 分析問題:
                        // 1、3秒鐘后調(diào)用函數(shù)(通過 this 的方式調(diào)用)
                        setTimeout(this.showMessage, 3000);
                    };


                    render() {
                        console.log("類組件的render被調(diào)用了");
                        return (
                            <div style={{ "backgroundColor": "pink" }}>
                                <h5 >我是類組件</h5>
                                <p>name:{this.props.name}</p>
                                <input type="button" value="調(diào)用帶著定時(shí)器的函數(shù)" onClick={this.handleClick} />
                            </div>
                        );
                    }
                }   
            ```

            **函數(shù)式組件:**

            ```js
            // 2、函數(shù)式組件
                function ComFn(props) {
                    console.log("函數(shù)式組件的函數(shù)被調(diào)用了");

                    //這個(gè)是閉包:
                    // 每調(diào)用一次父函數(shù)(ComFn),都會(huì)重新定義一個(gè)新的子函數(shù)。新的函數(shù)中保存著父函數(shù)新的形參
                    const showMessage = () => {
                        console.log('函數(shù)式組件: ' + props.name);
                    };

                    //這個(gè)是閉包:
                    //每調(diào)用一次父函數(shù)(ComFn),都會(huì)重新定義一個(gè)新的子函數(shù)。新的函數(shù)中保存著父函數(shù)新的形參
                    const handleClick = () => {
                        setTimeout(showMessage, 3000);
                    };
                   
                    return (
                        <div style={{ "backgroundColor": "skyblue" }}>
                            <h5 >我是函數(shù)式組件</h5>
                            <p>name:{props.name}</p>
                            {/*先點(diǎn)擊這個(gè)按鈕,調(diào)用,第一次定義的 showMessage和handleClick*/}
                            <input type="button" value="調(diào)用帶著定時(shí)器的函數(shù)" onClick={handleClick} />
                        </div>
                    );
                }
            ```

            **使用組件:**

            ```js
              let name = "張三瘋";
                function changeName() {
                    name = "張四瘋"
                    renderDom();
                }

                function renderDom() {
                    ReactDOM.render(
                        <div>
                            <button onClick={changeName} >修改</button>
                            <ComClass name={name} /><br />
                            <ComFn name={name} />
                        </div>, document.getElementById("box"));
                }

                renderDom();
            ```

            為什么react選擇了函數(shù)式組件1

            ### **2)、運(yùn)行:**

            **2.1)類組件:**

            點(diǎn)擊類組件的“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕后,再點(diǎn)擊”修改“按鈕(**注意先后順序**)。我們發(fā)現(xiàn)了:界面上打印的和控制臺(tái)打印的是**一樣的**。這是**不對(duì)的**:因?yàn)?,我點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕時(shí),name的值是”張三瘋“,應(yīng)該打印”張三瘋“

            為什么react選擇了函數(shù)式組件2

            **2.2)函數(shù)式組件:**

            點(diǎn)擊類組件的“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕后,再點(diǎn)擊”修改“按鈕(**注意先后順序**)。我們發(fā)現(xiàn)了:界面上打印的和控制臺(tái)里打印的**不一樣**,這是**對(duì)的**:因?yàn)?,我點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕時(shí),name的值是”張三瘋“,應(yīng)該打印”張三瘋“

            為什么react選擇了函數(shù)式組件3

            ### **3)總結(jié)**

            原因何在?以下文字要細(xì)細(xì)的品,如果品不出來,就結(jié)合上面的代碼,再看看。

            類組件:

            當(dāng)**類組件重新渲染**時(shí),**只調(diào)用了render函數(shù)**。組件的this不變。等定時(shí)器到了時(shí),讀取屬性的的值時(shí),先通過this找到props。再通過props找到name。而此時(shí),name的值,已經(jīng)發(fā)生了變化。所以,自然讀到的是新值“張四瘋” ,這個(gè)應(yīng)該好理解。

            函數(shù)式組件:

            (你必須對(duì)閉包是清楚的),當(dāng)**函數(shù)式組件重新渲染**時(shí),**調(diào)用了函數(shù)**(組件),那么在函數(shù)式組件里的 函數(shù)(showMessage,handleClick)就會(huì)被重新定義,新定義的函數(shù)保存著父函數(shù)(組件)的新的形參和局部變量。而我們點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)”時(shí),調(diào)用的是 第一次定義的showMessage,handleClick(這兩個(gè)函數(shù)里保存了父函數(shù)(組件)第一次傳入的形參和局部變量)。

            其實(shí),上面的代碼中,已經(jīng)做了注釋。我再次解釋后,如果不明白的話,看看下面的剖析原理的代碼。

             

            ### **2、看原理:**

            ### **1)用原生的方式剖析**

            與第一大點(diǎn)的第二小點(diǎn)的“剖析原理”一樣:

            函數(shù)式組件的剖析:

            ```js
            標(biāo)簽的方式使用函數(shù)式組件:
            <ComFn name={name} />
            基本上等價(jià)于:
            {ComFn({name})} //組件的方式使用,就是在調(diào)用函數(shù)
            ```

            類組件的剖析:

            ```js
            把new ComClass({name})實(shí)例化出來的對(duì)象,記錄起來了。

            1、定義一個(gè)對(duì)象,保存了new ComClass({name})
               //在react里對(duì)類組件對(duì)象進(jìn)行了保存。
               let comObj = new {new ComClass({name});

            2、在渲染時(shí),只是調(diào)用了類組件的render函數(shù)。
               comObj.render();
            ```

            ### **2)代碼(demo04):**

            類組件和函數(shù)式組件的代碼不用變(同第二大點(diǎn)的第一小點(diǎn):組件里使用定時(shí)器,并重新渲染組件)。

            **使用組件:**

            這個(gè)代碼等同于第一大點(diǎn)的第二小點(diǎn)。

            ```js
             let name = "張三瘋";
                let comObj = new ComClass({ name });
                function changeName() {
                    name = "張四瘋";
                    comObj.props = { name }
                    renderDom();
                }

                function renderDom() {       
                    ReactDOM.render(
                        <div>
                            <button onClick={changeName} >修改</button>
                            {comObj.render()}
                            {ComFn({name})}
                        </div>, document.getElementById("box"));
                }

                renderDom();

            ```

             

            ### **三、為什么react現(xiàn)在更推薦函數(shù)式組件**

            為什么react選擇了函數(shù)式組件4

            React的核心理念之一就是,**界面應(yīng)當(dāng)是數(shù)據(jù)的不同形式的簡單投影**。**相同的輸入應(yīng)該產(chǎn)生相同的輸出**。而函數(shù)式組件的寫法,使用閉包的特性,顯然符合這一理念:每個(gè)閉包里保存在父函數(shù)的當(dāng)前形參(props)和局部變量。而類組件里,由于,每次讀取數(shù)據(jù),要根據(jù)this指針去讀取,那必然不會(huì)讀取到屬于自己當(dāng)前狀態(tài)的值。而是更新后的最新的值。

             

            ### **四、補(bǔ)充:類組件如何解決以上問題呢:**

            其實(shí)還是利用了閉包。

            ### **看類組件的代碼修改(demo05):**

             

            ```js
            //修改類組件里的showMessage 和 handleClick 函數(shù)。

            showMessage = (name) => {
                console.log('類組件: ' + name);
            };

            handleClick = () => {
                let name = this.props.name;
                //此處:
                //1 、()=>this.showMessage(name)是閉包。父函數(shù)是handleClick,
                //2、閉包會(huì)把當(dāng)前的局部變量name持有,然后,調(diào)用 showMessage(name)時(shí),把name的值傳入showMessge里
                setTimeout(()=>this.showMessage(name), 3000);
            };

            ```

             

            ### **五、類組件和函數(shù)式組件區(qū)別:**

            在react的模式和開發(fā)思維上,函數(shù)組件和類組件還是有區(qū)別的。

            1、各自的特點(diǎn):

            1)類的組件主要是面向?qū)ο缶幊?,是建立在繼承之上,它的生命周期等核心概念的特點(diǎn)  2)函數(shù)組件主要是函數(shù)式編程,無副作用,并且在引用的時(shí)候透明的特點(diǎn)

            2、使用場景:

            因?yàn)閮烧咧鞔虻奶攸c(diǎn)不一樣,所以在使用場景上自然就存在一些差異了: 如果組件依賴生命周期,并且它的設(shè)計(jì)上需要繼承的特性,我們?cè)谶x擇上更傾向類組件會(huì)更合適一點(diǎn)

            由于HOOK的推出,逐漸降低了生命周期的概念,那么函數(shù)組件可以更好的取代類組件的開發(fā),而且官方也推崇“組合優(yōu)于繼承”的思想,所以類組件的優(yōu)勢(shì)也在慢慢的淡出。更多關(guān)于web培訓(xùn)的問題,歡迎咨詢千鋒教育在線名師。千鋒教育擁有多年IT培訓(xùn)服務(wù)經(jīng)驗(yàn),采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,擁有國內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),助力更多學(xué)員實(shí)現(xiàn)高薪夢(mèng)想。

            tags:
            聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
            10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
            請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
            免費(fèi)領(lǐng)取
            今日已有369人領(lǐng)取成功
            劉同學(xué) 138****2860 剛剛成功領(lǐng)取
            王同學(xué) 131****2015 剛剛成功領(lǐng)取
            張同學(xué) 133****4652 剛剛成功領(lǐng)取
            李同學(xué) 135****8607 剛剛成功領(lǐng)取
            楊同學(xué) 132****5667 剛剛成功領(lǐng)取
            岳同學(xué) 134****6652 剛剛成功領(lǐng)取
            梁同學(xué) 157****2950 剛剛成功領(lǐng)取
            劉同學(xué) 189****1015 剛剛成功領(lǐng)取
            張同學(xué) 155****4678 剛剛成功領(lǐng)取
            鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
            董同學(xué) 138****2867 剛剛成功領(lǐng)取
            周同學(xué) 136****3602 剛剛成功領(lǐng)取
            相關(guān)推薦HOT
            抖音小店照片要求尺寸多大

            在抖音平臺(tái)開設(shè)小店已經(jīng)成為了越來越多人的選擇,相信大家已經(jīng)在各大社交平臺(tái)上看到有不少小店的推廣。在抖音上,照片是展示產(chǎn)品的重要手段,因...詳情>>

            2023-10-08 16:14:25
            抖音招商團(tuán)長托管服務(wù)費(fèi)怎么退回來

            抖音招商團(tuán)長托管服務(wù)是抖音為有意愿創(chuàng)作內(nèi)容并帶動(dòng)其他創(chuàng)作者成為團(tuán)隊(duì)成員的用戶提供的一種服務(wù)。通過該服務(wù),招商團(tuán)長可以自主組建團(tuán)隊(duì)并得到...詳情>>

            2023-10-08 16:08:53
            抖音小店怎么做代銷

            抖音已經(jīng)成為了一個(gè)非常受歡迎的短視頻應(yīng)用程序,在其中許多用戶都精心打造了自己的小店,用于銷售各種各樣的商品,獲取額外的收入。然而,要想...詳情>>

            2023-10-08 15:28:41
            怎樣開抖音小店帶貨賺錢

            隨著直播帶貨的火熱,越來越多的人開始嘗試通過抖音小店來開展帶貨業(yè)務(wù)。抖音小店是抖音直播帶貨的配套,可以讓用戶在購買直播中產(chǎn)品時(shí)就實(shí)現(xiàn)購...詳情>>

            2023-10-08 15:06:36
            能不能幫我打開抖音小店店鋪呢怎么弄

            抖音小店是近年來非常火爆的一個(gè)網(wǎng)絡(luò)業(yè)務(wù),也是提供了很多商業(yè)機(jī)會(huì)的平臺(tái)。對(duì)于一個(gè)創(chuàng)業(yè)者而言,開設(shè)抖音小店是一個(gè)不錯(cuò)的選擇。但是,許多小店...詳情>>

            2023-10-08 15:01:21