Isaac
Isaac

Reputation: 12874

useEffect unable to invoke function directly?

VersionA: useEffect(() => doRequest(), []);

VersionB:

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

I've always thought both the version are exactly the same, where VersionA is a shortcut and VersionB allowing you to do more than single command within the inline function.

However when I use VersionA, I'm hitting TypeError: func.apply is not a function, threw by NextJS

enter image description here

If I use syntax of VersionB, everything working fine. Wondering if anyone faced this before?

UPDATES The full code for my component

import { useEffect } from 'react';
import useRequest from '../../hooks/use-request';
import Router from 'next/router';

export default () => {
  const { doRequest } = useRequest({
    url: '/api/users/signout',
    method: 'post',
    body: {},
    onSuccess: () => Router.push('/'),
  });

  useEffect(() => doRequest(), []);
  return <div>Signing you out...</div>;
};

Upvotes: 0

Views: 492

Answers (2)

trixn
trixn

Reputation: 16334

It's not exactly the same.

useEffect(() => doRequest(), []);

In this case your callback will implicitly return the value that doRequest() returns. A useEffect callback can only return a function (for cleanup of the effect) or undefined. You can use that syntax if doRequest either returns nothing (meaning undefined) or a cleanup function.

EDIT: As noted by @3limin4t0r () => fn() is the same as () => { return fn(); }:

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

By having a function body and not explicitly returning something your function implicitly returns undefined which is fine if there is nothing to cleanup.

Upvotes: 4

James Craig
James Craig

Reputation: 6854

This is written about in the official docs here.

Any function returned from useEffect is used for "cleaning up".

In your first example doRequest returns something other than undefined, which React will try to call as a function to "clean up" when the component unmounts.

Example of useEffect with a clean up function:

useEffect(() => {
  document.addEventListener("resize", handleResize);
  // This is a "clean up" function
  return () => {
    document.removeEventListener("resize", handleResize);
  };
}, []);

Example of useEffect without a clean up function. Note this is bad as the listener will still fire after the component unmounts.

useEffect(() => {
  document.addEventListener("resize", handleResize);
}, []);

Upvotes: 0

Related Questions