Home > Net >  Can anyone give more info about the useEffect hook based on experience
Can anyone give more info about the useEffect hook based on experience

Time:12-03

I understand a bit about the useEffect hook but I think there’s still more knowledge to grasp. Some of which are not in the documentation. Please any contribution will help a lot y’all.

Some of my questions are:

  1. Does useEffect get called on initial render even in production just like in development?

  2. If it does, how do we control this the best way?

  3. How can we use a clean up function on this Hook?

  4. How can we make asynchronous calls in useEffect?

My attempts on useEffect usually makes me feel like a bad developer

CodePudding user response:

Please take a look at react docs and react beta docs.

  1. It always runs when your component mounts, after the first render regardless of the environment. In development mode when strict mode is on, it runs twice:

When Strict Mode is on, React will run one extra development-only setup cleanup cycle before the first real setup. This is a stress-test that ensures that your cleanup logic “mirrors” your setup logic and that it stops or undoes whatever the setup is doing. If this causes a problem, you need to implement the cleanup function.

  1. I'm not really sure what you mean by controlling it the best way. Your effect or setup code runs whenever the component mounts. Maybe How to handle the Effect firing twice in development? can help you. You sometimes might want to prevent the effect to be executed when the component mounts, you can skip the effect by using a ref. See this stackoverflow question

  2. The function you return in the useEffect does the clean up for you. See. For instance if you add an event listener inside useEffect, you remove the listener inside the function you return inside of it. See this link

  useEffect(() => {
    const listener = () => { /* Do something */ };

    window.addEventListener("click", listener);

    return () => {
      window.removeEventListener("click", listener);
    };
  }, []);
  1. Yes you can. See this stackoverflow question and fetching data in docs
  useEffect(() => {
    async function asyncFunction() {
      /* Do something */
    }

    asyncFunction();
  }, []);

Update:

Take a look at You Might Not Need an Effect . It explains some situations which you might not need an effect at all.

Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone.

Update 2:

You can probably skip this part for now, but it might help you to have a better grasp of useEffect, event handlers and what to expect in the future.

Separating Events from Effects tries to explain the differences between effects and event handlers, why distinguishing between those two is important and using event handlers inside effects.

Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if some value they read, like a prop or a state variable, is different from what it was during the last render. Sometimes, you also want a mix of both behaviors: an Effect that re-runs in response to some values but not others. This page will teach you how to do that.

Sometimes, you might use an event handler which has access to the props or the state inside an effect. But you don't want the useEffect to be triggered every time the values used in the event handler change. The following example is taken form useEffect shouldn’t re-fire when event handlers change .

function Chat({ selectedRoom }) {
  const [muted, setMuted] = useState(false);
  const theme = useContext(ThemeContext);

  useEffect(() => {
    const socket = createSocket('/chat/'   selectedRoom);
    socket.on('connected', async () => {
      await checkConnection(selectedRoom);
      showToast(theme, 'Connected to '   selectedRoom);
    });
    socket.on('message', (message) => {
      showToast(theme, 'New message: '   message);
      if (!muted) {
        playSound();
      }
    });
    socket.connect();
    return () => socket.dispose();
  }, [selectedRoom, theme, muted]); //            
  • Related