jsx-eslint / eslint-plugin-react

React-specific linting rules for ESLint
MIT License
8.86k stars 2.76k forks source link

Rule proposal: Prefer memoized callback functions #3683

Open oliveryasuna opened 5 months ago

oliveryasuna commented 5 months ago

Consider the following:

// Option 1.
const MyComponent = () => {
  return <div onClick={() => console.log('clicked')}>Click me</div>;
};

// Option 2.
const MyComponent = () => {
  const handleClick = () => {
    console.log('clicked');
  };

  return <div onClick={handleClick}>Click me</div>;
};

Both options behave the same. The callback is recreated on every re-render. One might prefer to memoized the callback to avoid this common pitfall:

// Option 3.
const MyComponent = () => {
  const handleClick = useCallback(() => {
    console.log('clicked');
  }, []);

  return <div onClick={handleClick}>Click me</div>;
};

I propose a new rule that reports when a callback function is defined in JSX or would be recreated on every re-render. More generally, such a rule could allow developers to prefer one pattern over the other.

Note: I opened this issue is conjunction with https://github.com/jsx-eslint/eslint-plugin-react/issues/3682.

ljharb commented 5 months ago

I agree (when using React >= 16.9) there's value in ensuring that any function created in the render path is memoized with useCallback.