Skip to content

Bug: [eslint-plugin-react-hooks] exhaustive-deps false positive on "unnecessary" dependency if its a React component #18051

Open
@zeorin

Description

@zeorin

Steps to reproduce

  1. create a memoized value using useMemo
  2. a React component is used in the creation of this value, in a JSX expression
  3. specify the React component in the dependency array

Link to code example: https://github.com/zeorin/eslint-plugin-react-hooks-repro

The current behavior

React Hook useMemo has an unnecessary dependency: 'Component'. Either exclude it or remove the dependency array react-hooks/exhaustive-deps

The expected behavior

No lint errors.

More details

A simple repro (taken from the link above) is:

function Foo({ component: Component }) {
	const memoized = useMemo(() => ({
		render: () => <Component />
	}), [Component]);

	return memoized.render();
}

Workarounds

If one changes the component to lowercase, the lint error goes away. It does also mean that we need to change the way we render the component:

function Foo({ component }) {
	const memoized = useMemo(() => ({
		render: component
	}), [component]);

	return memoized.render();
}

Alternatively we can decide not to use JSX, in which case the lint rule functions correctly, too:

function Foo({ component: Component }) {
	const memoized = useMemo(() => ({
		render: () => React.createElement(Component)
	}), [Component]);

	return memoized.render();
}

Impact

Currently it is hard to use props that are components in a JSX expression if one is using the exhaustive-deps rule.

This is also compounded by the fact that this rule has a ESLint fix that removes the dependency, thus changing the behaviour of the code and leading to bugs. See #16313 for that bug report.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions