簡體   English   中英

React hooks:什么/為什么`useEffect`?

[英]React hooks: What/Why `useEffect`?

關於新提出的React Effect Hook

  1. Effect鈎子( useEffect() )的優點和用例是什么?

  2. 為什么它更可取?它與componentDidMount/componentDidUpdate/componentWillUnmount (性能/可讀性)有何不同?

該文件指出:

函數組件的主體(稱為 React 的渲染階段)內不允許發生突變、訂閱、計時器、日志記錄和其他副作用。

但我認為在諸如 componentDidUpdate 等生命周期方法而不是渲染方法中擁有這些行為已經是常識。

還提到:

傳遞給 useEffect 的函數將在渲染提交到屏幕后運行。

但這不是componentDidMountcomponentDidUpdate所做的嗎?

  1. Effect鈎子( useEffect() )的優點和用例是什么?

    優點

    首先,鈎子通常可以提取和重用跨多個組件通用的有狀態邏輯,而無需承擔高階組件或渲染道具的負擔。

    第二個好處(特別是 Effect 鈎子)是避免在componentDidUpdate中沒有正確處理依賴狀態的副作用時可能出現的錯誤(因為 Effect 鈎子確保在每次渲染時設置和拆除此類副作用) .

    另請參閱下面詳述的性能和可讀性優勢。

    用例

    任何使用生命周期方法實現有狀態邏輯的組件——Effect 鈎子都是“更好的方法”。

  2. 為什么它更可取?它與componentDidMount / componentDidUpdate / componentWillUnmount (性能/可讀性)有何不同?

    為什么更可取

    因為上面和下面詳述的優點。

    它與生命周期方法有何不同

    表現

    效果掛鈎——

    • 感覺比生命周期方法更具響應性,因為它們不會阻止瀏覽器更新屏幕;
    • 然而,每次渲染都會設置和拆除副作用,這可能很昂貴……
    • ...所以可以優化為完全跳過,除非特定狀態已更新。

    可讀性

    效果掛鈎導致:

    • 更簡單和更易於維護的組件,因為能夠將以前必須在同一組生命周期方法中表達的不相關行為拆分為每個此類行為的單個鈎子 - 例如:

       componentDidMount() { prepareBehaviourOne(); prepareBehaviourTwo(); } componentDidUnmount() { releaseBehaviourOne(); releaseBehaviourTwo(); }

      變成:

       useEffect(() => { prepareBehaviourOne(); return releaseBehaviourOne; }); useEffect(() => { prepareBehaviourTwo(); return releaseBehaviourTwo; });

      注意,有關代碼BehaviourOne現在清楚地從與分離BehaviourTwo ,而在此之前這是每個生命周期方法中的混雜。

    • 更少的樣板,因為不需要在多個生命周期方法中重復相同的代碼(例如componentDidMountcomponentDidUpdate之間很常見)——例如:

       componentDidMount() { doStuff(); } componentDidUpdate() { doStuff(); }

      變成:

       useEffect(doStuff); // you'll probably use an arrow function in reality

這是ReactConf2018 Dan Abramov 的演講中解釋差異的一個例子:


以下是以下示例的一些發現:

  1. 您將使用鈎子編寫更少的樣板代碼
  2. 使用useEffect()訪問生命周期更新和狀態更新
  3. 關於性能一方面是:

與 componentDidMount 和 componentDidUpdate 不同,傳遞給 useEffect 的函數在布局和繪制后觸發,在延遲事件期間

  1. 代碼共享太容易了,並且可以在同一個組件中針對不同目的多次實現 useEffect()。
  2. 您可以通過將數組作為第二個參數傳遞給useEffect()鈎子來更有效地控制組件重新渲染,這在您僅在安裝和卸載時僅傳遞空數組 [] 來渲染組件時非常有效。
  3. 使用多個useEffect()鈎子來分離關注點並做出反應:

Hooks 允許我們根據代碼正在做什么而不是生命周期方法名稱來拆分代碼。 React 將按照指定的順序應用組件使用的每個效果


使用類:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }

  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

使用鈎子:

import { useState, useEffect } from 'react';

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

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

useEffect 在狀態改變時運行。

import { useState, useEffect } from 'react';
function Example() {
  const [Age, setAge] = useState(33);
  const [Somestate,setSomestate]=useState(initilaestate);
  useEffect(() => {
    console.log('the age is changed to ',Age);
  });

// you can use useEffect as many times you want in you component 
  useEffect(() => {
    console.log('the age is changed to ',Age);
  },[someState]);//here you tell useEffect what state to watch if you want to watch the changing of a  particular state and here we care about someState
  return (
    <div>
      <p>age increased to  {Age}</p>
      <button onClick={() => setAge(count + 1)}>
       Increase age by One
      </button>
    </div>
  );
}
```

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM