Why is the cleanup function from `useEffect` called on every render?

Joji :

I've been learning React and I read that the function returned from useEffect is meant to do cleanup and React performs the cleanup when the component unmounts.

So I experimented with it a bit but found in the following example that the function was called every time the component re-renders as opposed to only the time it got unmounted from the DOM, i.e. it console.log("unmount"); every time the component re-renders.

Why is that?

function Something({ setShow }) {
  const [array, setArray] = useState([]);
  const myRef = useRef(null);

  useEffect(() => {
    const id = setInterval(() => {
      setArray(array.concat("hello"));
    }, 3000);
    myRef.current = id;
    return () => {
      console.log("unmount");
      clearInterval(myRef.current);
    };
  }, [array]);

  const unmount = () => {
    setShow(false);
  };

  return (
    <div>
      {array.map((item, index) => {
        return (
          <p key={index}>
            {Array(index + 1)
              .fill(item)
              .join("")}
          </p>
        );
      })}
      <button onClick={() => unmount()}>close</button>
    </div>
  );
}

function App() {
  const [show, setShow] = useState(true);

  return show ? <Something setShow={setShow} /> : null;
}

Live example: https://codesandbox.io/s/vigilant-leavitt-z1jd2

Avin Kavish :

React performs the cleanup when the component unmounts.

これをどこで読んだかわかりませんが、この説明は正しくありません。そのフックへの依存関係が変更され、新しい値でエフェクトフックを再度実行する必要がある場合、Reactはクリーンアップを実行しますこの動作は、変化するデータに対するビューの反応性を維持するためのものです。公式の例として、アプリが友達のプロフィールからのステータス更新をサブスクライブするとします。あなたは素晴らしい友達なので、あなたは彼らの友達をはずし、他の誰かと友達になることにします。これで、アプリは前の友達のステータス更新の登録を解除し、新しい友達の更新を聞く必要があります。これは自然で、useEffect動作方法を使用して簡単に実現できます。

 useEffect(() => { 
    chatAPI.subscribe(props.friend.id);

    return () => chatAPI.unsubscribe(props.friend.id);
  }, [ props.friend.id ])

依存関係リストにフレンドIDを含めることで、フレンドIDが変更されたときにのみフックを実行する必要があることを示すことができます。

In your example you have specified the array in the dependency list and you are changing the array at a set interval. Every time you change the array, the hook reruns.

You can achieve the correct functionality simply by removing the array from the dependency list and using the callback version of the setState hook. The callback version always operates on the previous version of the state, so there is no need to refresh the hook every time the array changes.

  useEffect(() => {
    const id = setInterval(() => setArray(array => [ ...array, "hello" ]), 3000);

    return () => {
      console.log("unmount");
      clearInterval(id);
    };
  }, []);

Some additional feedback would be to use the id directly in clearInterval as the value is closed upon (captured) when you create the cleanup function. There is no need to save it to a ref.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

useEffect cleaning function is not called when tab is closed

分類Dev

Why ordinary function is not called there?

分類Dev

Why my React component is still updating state even if I do cleanup in useEffect()?

分類Dev

Why is my function not being called?

分類Dev

When called inside a function with parameters passed from parent, why is the setTimeout function logging undefined?

分類Dev

C++ templates: why is not the specialized function called?

分類Dev

Why $.ajax() call back function are never called?

分類Dev

In loop condition: why is strlen() called every time, but vector.size() gets called only once?

分類Dev

Xamarin forms DisplayAlert not showing when called from a function called by a delegate

分類Dev

Get element from which onclick function is called

分類Dev

Reloading UITableViewController from outside a function called in viewDidLoad

分類Dev

how to use fresh state inside the useeffect, but execute cleanup on unmount only

分類Dev

accessibilityPerformMagicTap not called every time

分類Dev

exit/break main function from called/child function

分類Dev

Is there a performance hit when methods returning JSX are called in render function of React component whenver any state is changed?

分類Dev

Can I call an event handler with a parameter using inline declaration of the parameter without having the function be recreated on every render?

分類Dev

Why the constructor is called if the class have a method (function) with his name?

分類Dev

JS newbie: Why is this function inside a for loop called only once?

分類Dev

Asyncio function works when called from script but not from Flask route

分類Dev

Return value from setInterval() function called from html

分類Dev

Why is useEffect not being triggered?

分類Dev

Why do lifetimes differ when a function is called in a closure vs. being called directly in Rust?

分類Dev

How to render different data every time upon clicking each item from a list of .map items?

分類Dev

make useEffect fire before render JSX part

分類Dev

make useEffect fire before render JSX part

分類Dev

React call component's method from nested function in render method

分類Dev

try to render data from 2 different source using .map() function

分類Dev

Re render when data from async function is ready

分類Dev

Re render when data from async function is ready

Related 関連記事

  1. 1

    useEffect cleaning function is not called when tab is closed

  2. 2

    Why ordinary function is not called there?

  3. 3

    Why my React component is still updating state even if I do cleanup in useEffect()?

  4. 4

    Why is my function not being called?

  5. 5

    When called inside a function with parameters passed from parent, why is the setTimeout function logging undefined?

  6. 6

    C++ templates: why is not the specialized function called?

  7. 7

    Why $.ajax() call back function are never called?

  8. 8

    In loop condition: why is strlen() called every time, but vector.size() gets called only once?

  9. 9

    Xamarin forms DisplayAlert not showing when called from a function called by a delegate

  10. 10

    Get element from which onclick function is called

  11. 11

    Reloading UITableViewController from outside a function called in viewDidLoad

  12. 12

    how to use fresh state inside the useeffect, but execute cleanup on unmount only

  13. 13

    accessibilityPerformMagicTap not called every time

  14. 14

    exit/break main function from called/child function

  15. 15

    Is there a performance hit when methods returning JSX are called in render function of React component whenver any state is changed?

  16. 16

    Can I call an event handler with a parameter using inline declaration of the parameter without having the function be recreated on every render?

  17. 17

    Why the constructor is called if the class have a method (function) with his name?

  18. 18

    JS newbie: Why is this function inside a for loop called only once?

  19. 19

    Asyncio function works when called from script but not from Flask route

  20. 20

    Return value from setInterval() function called from html

  21. 21

    Why is useEffect not being triggered?

  22. 22

    Why do lifetimes differ when a function is called in a closure vs. being called directly in Rust?

  23. 23

    How to render different data every time upon clicking each item from a list of .map items?

  24. 24

    make useEffect fire before render JSX part

  25. 25

    make useEffect fire before render JSX part

  26. 26

    React call component's method from nested function in render method

  27. 27

    try to render data from 2 different source using .map() function

  28. 28

    Re render when data from async function is ready

  29. 29

    Re render when data from async function is ready

ホットタグ

アーカイブ