简体   繁体   中英

I have read the React Docs on Hooks and I'm confused. When is the useEffect Hook clean up function called?

The react docs explanation on when the useEffect clean up function is called is confusing and generic to be honest. They even confuse you more by comparing the class mental model with hooks. Class based components work differently from function based components with hooks. React remembers the effect function you provided to useEffect, and runs it after flushing changes to the DOM which is understandable. Now how and when is the function which is returned ("clean up function") called?

Code example below:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

The function returned from the function given as first argument to useEffect will be called when any element in the array given as second argument changes, or on every render if no second argument is given, or when the component is unmounted.

Example

 const { useEffect, useState } = React; function MyComponent({ prop }) { useEffect(() => { console.log('Effect!'); return () => console.log('Cleanup!') }, [prop]) return ( <div>{prop}</div> ); } function App() { const [value, setValue] = useState(0); useEffect(() => { setInterval(() => { setValue(value => value + 1); }, 1000) }, []) return value < 3 ? <MyComponent prop={value} /> : null; } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

Without using the second parameter it will get called on every render.

This is often overkill, so it often a good idea to use the second parameter even if it's empty [] ..

eg.

useEffect(() => {....}, []);

Doing the above will only then call the cleanup when the component is physically detached from the DOM.

You can also pass props instead of [] , this is handy if say a prop change, like what chat room you was in, it would then cleanup the current chat room, and initialize the new chat room etc.

So in your example passing [props.friend.id] would make sense, because if the id changed, it would make sense to call the cleanup, and then run the effect again for the new id.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM