Rodrigo Olivares
Rodrigo Olivares

Reputation: 63

Anonymous function vs named function on event handlers

I've been searching around for a long time, but I coudn't find out. Can anyone tell me if there is (and if there is, what is the) difference between using anonymous or named function on event handlers?

Example 1:

...
onClick={() => toggleStatus(!status)}

Example 2:

function handleToggleStatus() {
  toggleStatus(!status);
}
...
onClick={handleToggleStatus}

Upvotes: 2

Views: 2645

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074839

The short version: No, there isn't (at least in a React-specific way; one nice thing about named functions is that they have names, which can be handy in call stacks / stack traces).

The long version: The reason you may have seen people saying not to do onClick={() => toggleStatus(!status)} isn't that it's an anonymous function; it's that it's a function that gets re-created on every render. That means that the component it's being used on sees a different function on every render. If that component is memoized on its props and your component is being re-rendered for reasons unrelated to that component, that can be unnecessary work. In that case, you might want to use useCallback to have a stable function you can provide to the component:

const handleToggleStatus = useCallback(
    () => toggleStatus((status) => !status), // Assuming it allows functional updates
    []
);

Or:

const handleToggleStatus = useCallback(
    () => toggleStatus(!status), // If it doesn't allow functional updates
    [status] // <== Note dependency
);

Those functions are anonymous and recreated every time,¹ but useCallback will return the earlier version if the dependencies haven't changed as a performance optimization, allowing a memoized component to avoid re-rendering.

More about useCallback (and useMemo and such) and memoization in my answer here.


¹ "Those functions are anonymous and recreated every time..." They don't have to be anonymous, there's no reason you can't use a named function expression:

const handleToggleStatus = useCallback(
    function handleToggleStatus() { toggleStatus((status) => !status); }, // Assuming it allows functional updates
    []
);

Or:

const handleToggleStatus = useCallback(
    function handleToggleStatus() { toggleStatus(!status); }, // If it doesn't allow functional updates
    [status] // <== Note dependency
);

Upvotes: 7

Related Questions