第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用在 React 中未正確調(diào)用自定義鉤子內(nèi)部的效果

使用在 React 中未正確調(diào)用自定義鉤子內(nèi)部的效果

慕姐8265434 2022-09-29 15:28:16
我正在使用一個名為的自定義鉤子,我在兩個組件(第一,第二)中使用它,但僅在和組件得到渲染時才被調(diào)用。useEffectuseCustomHookuseCustomHookuseEffectFirstSecond例如我有第一個組件import React,{useState} from 'react'import useCustomHook from './customHook'function First(){ console.log("component First rendering") const [count,setCount]=useState(0) useCustomHook(count) return (<div>First component</div>)}這是我的第二個組成部分import React,{useState} from 'react'import useCustomHook from './customHook'function Second(){ console.log("component Second rendering") const [count,setCount]=useState(0) useCustomHook(count) return (<div>Second component</div>)}這是我的自定義鉤子import {useEffect} from 'react'function useCustomHook(count){  console.log("useCustomHook getting called")  useEffect(()=>{ console.log("useEffect gets called") //this function is running after both component rendered  },[count])}我的主要應用組件import First from './first'import Second from './second'function App(){   return (      <div>        <First/>        <Second/>      </div>    )}我的控制臺輸出是 :1) 組件首次渲染2)使用被調(diào)用的自定義鉤子3) 組件 二次渲染4)使用被調(diào)用的自定義鉤子5) (2) 使用效果被調(diào)用我想知道為什么是行輸出不是在行之后,為什么組件日志發(fā)生在行之后,因為應該在被組件調(diào)用之后但在調(diào)用組件日志之前調(diào)用。為什么在組件日志之前沒有被調(diào)用。52Second2useEffectuseCustomHookFirstSeconduseEffectuseCustomHookSecond
查看完整描述

2 回答

?
暮色呼如

TA貢獻1853條經(jīng)驗 獲得超9個贊

您的輸出是應該的。

我認為你對輸出感到困惑,因為你認為這與輸出相同,但這是不正確的。它們都是不同的,它們之間的幾個重要區(qū)別如下:useEffectcomponentDidMount

它們在不同的時間運行

(與您的問題相關(guān))

它們都是在組件的初始呈現(xiàn)之后調(diào)用的,但在瀏覽器繪制屏幕之后調(diào)用,而在瀏覽器繪制屏幕之前調(diào)用。useEffectcomponentDidMount

捕捉道具和狀態(tài)

(與您的問題無關(guān),請隨時跳到答案的末尾)

useEffect捕獲狀態(tài)和道具,而不這樣做。componentDidMount

請考慮以下代碼片段,以了解使用效果捕獲狀態(tài)和道具的含義。

class App extends React.Component {

  constructor() {

    super();

    this.state = {

      count: 0

    };

  }


  componentDidMount() {

    setTimeout(() => {

      console.log('count value = ' + this.state.count);

    }, 4000);

  }


  render() {

    return (

      <div>

        <p>You clicked the button { this.state.count } times</p>

        <button

          onClick={ () => this.setState(prev => ({ count: prev.count + 1 })) }>

          Increment Counter

        </button>

      </div>

    );

  }

}


ReactDOM.render(<App />, document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>


<div id="root"></div>

function App() {

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


  React.useEffect(() => {

    setTimeout(() => {

      console.log('count value = ' + count);

    }, 4000);

  }, [])

  

  return (

    <div>

      <p>You clicked the button { count } times</p>

      <button

        onClick={ () => setCount(count + 1) }>

        Increment Counter

      </button>

    </div>

  );

}


ReactDOM.render(<App />, document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>


<div id="root"></div>

兩個代碼片段是相同的,除了第一個代碼片段具有基于類的組件,第二個代碼片段具有功能組件。

這兩個代碼段都有一個名為 狀態(tài)的變量,它們都在 4 秒后將變量的值記錄到控制臺。它們還包括一個按鈕,可用于遞增 .countcountcount

嘗試單擊按鈕(4 或 5 次),然后將 的值記錄在控制臺上。count

如果您認為這一點并且相同,那么您可能會驚訝地發(fā)現(xiàn)兩個代碼片段在4秒后都記錄了不同的變量值。componentDidMountuseEffectcount

基于類的代碼段記錄最新值,而基于函數(shù)組件的代碼段記錄變量的初始值。count

它們記錄變量的不同值的原因是:count

  • this.state類內(nèi)部組件始終指向最新狀態(tài),因此它會記錄 4 秒后的最新值。count

  • useEffect 捕獲變量的初始值,并記錄捕獲的值而不是最新值。count

有關(guān) 和 之間的差異的深入說明,我建議您閱讀以下文章useEffectcomponentDidMount


回到你的問題

如果您注意了我的答案中與您的問題相關(guān)的第一部分,那么您現(xiàn)在可能明白了為什么在安裝和組件后運行其回調(diào)。useEffectFirstSecond

如果沒有,那么讓我解釋一下。

在執(zhí)行從組件內(nèi)部調(diào)用的函數(shù)后,將掛載組件,如果它是基于類的組件,則此時將調(diào)用其生命周期函數(shù)。useCustomHookFirstFirstcomponentDidMount

在組件掛載后,組件掛載,如果這也是一個基于類的組件,則此時將調(diào)用其生命周期函數(shù)。FirstSecondcomponentDidMount

安裝完兩個組件后,瀏覽器將繪制屏幕,因此,您會在屏幕上看到輸出。瀏覽器繪制完屏幕后,將對和組件執(zhí)行 useEffect 的回調(diào)函數(shù)。FirstSecond

簡而言之,讓瀏覽器在運行其效果/回調(diào)之前繪制屏幕。這就是為什么記錄在輸出的末尾。useEffectuseEffect gets called

您可以在官方文檔上查看有關(guān)此內(nèi)容的更多詳細信息:效果時間

如果將 和 組件轉(zhuǎn)換為類組件,則輸出將如下所示:FirstSecond

1. component First rendering

2. component Second rendering

3. component First mounted.      // console.log statement inside componentDidMount

4. component Second mounted.     // console.log statement inside componentDidMount

您可能希望第 3 行位于第 2 位,第 2 行位于第 3 位,但事實并非如此,因為 react 首先執(zhí)行所有子組件的渲染函數(shù),然后再將它們插入 DOM 中,并且只有在它們插入到 DOM 中之后,每個組件才會執(zhí)行。componentDidMount


如果創(chuàng)建 和 組件并創(chuàng)建類組件的以下層次結(jié)構(gòu):ThirdFourth


App

 |__ First

 |     |__ Third

 |          |__ Fourth

 | 

 |__ Second

然后,您將獲得以下輸出:


1.  First component constructor

2.  component First rendering

3.  Third component constructor

4.  component Third rendering

5.  Fourth component constructor

6.  component Fourth rendering

7.  Second component constructor

8.  component Second rendering

9.  component Fourth mounted

10. component Third mounted

11. component First mounted

12. component Second mounted


查看完整回答
反對 回復 2022-09-29
?
倚天杖

TA貢獻1828條經(jīng)驗 獲得超3個贊

你提到的順序完全有道理,這就是鉤子的工作原理。

流:

  • First組件開始執(zhí)行。

  • 在組件中,在代碼行之后,將執(zhí)行FirstuseCustomHook(count)useCustomHook

  • 在控制臺中.log,并執(zhí)行 useEffect,并且使用效果采取的回調(diào)為“已注冊”和“未執(zhí)行”。useCustomHook

  • First組件返回 JSX。即組件被安裝/渲染。

  • 一旦組件被掛載,就會調(diào)用使用效果的回調(diào)。FirstuseCustomHook

  • 基本上,組件內(nèi)部的范圍限定為組件。useCustomHookFirst

第二組件也是如此...


查看完整回答
反對 回復 2022-09-29
  • 2 回答
  • 0 關(guān)注
  • 115 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號