question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Could useMemo and useCallback have closures (functions) as the last argument?

See original GitHub issue

The current argument order is

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

and so on.

It makes it the code less readable when the callback spans multiple lines: it is hard to relate the dependencies to the hook.

What if the dependencies could be written as the first argument?

const memoizedValue = useMemo([a, b], () => computeExpensiveValue(a, b));

const memoizedCallback = useCallback(
  [a, b]
  () => {
    doSomething(a, b);
  }
);

useEffect(
  [props.source],
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  }
);

For instance, the last example becomes easier to reason: there’s an effect that is run whenever props.source changes.

AFAIK JavaScript does not yet allow to move the last closure argument out of the function call parenthesis, however, the following formatting might make sense:

useEffect([props.source], () => {
  const subscription = props.source.subscribe();
  return () => {
    subscription.unsubscribe();
  };
});

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:15

github_iconTop GitHub Comments

1reaction
bvaughncommented, May 26, 2020

The APIs being discussed have already been released and have been in use for over a year. Changing them would cause a lot of churn throughout the ecosystem. The bar for doing this is be very high (e.g. they are causing runtime errors) rather than a subjective preference about readability.

We appreciate the thought and discussion that went into this issue, but it’s not a change we can make given the impact it would have on thousands of downstream packages and apps.

Thanks for understanding!

0reactions
vlsicommented, May 26, 2020

@bvaughn ,

Frankly speaking, I do not see how it causes “runtime errors”. There change to add useMemo(deps, function) is backward-compatible. I see how it might introduce confusion, however, I don’t see how it introduces errors (including runtime ones).

It would be nice if you could prefer having lambdas as the last argument in case the only argument is lambda.

Read more comments on GitHub >

github_iconTop Results From Across the Web

useCallback vs useMemo - Medium
useCallback and useMemo both expect a function and an array of dependencies. The difference is that useCallback returns its function when the dependencies ......
Read more >
When to useMemo and useCallback - Kent C. Dodds
useMemo is similar to useCallback except it allows you to apply memoization to any value type (not just functions). It does this by...
Read more >
useCallback vs. useMemo and when to use them [duplicate]
The differences: useMemo will memoize/remember the value that is returned from the function you pass into it until the dependancies change.
Read more >
React Hooks - useCallback vs. useMemo -- newline
React Hooks - useCallback vs. useMemo. May 10th, 2021 ... Returns an anonymous closure function that acts as the original function with the...
Read more >
How to useMemo and useCallback: you can remove most of ...
useCallback and useMemo for props don't prevent re-renders by themselves. Only when every single prop and the component itself are memoized, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found