Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: eslint-plugin-react-hooks disallows the use of useId in async component even though it works #31187

Closed
axeleroy opened this issue Oct 11, 2024 · 6 comments

Comments

@axeleroy
Copy link

In #27045 the eslint-plugin-react-hooks has been modified to disallow the use of any hooks in async components, justified by this sentence:

Hooks cannot be called in async functions, on either the client or the server.

However, some hooks can be called in async components, namely useId. Or at least the documentation does not mention it1.

React version: 18.3.1
eslint-plugin-react-hooks: 5.0.0

Steps To Reproduce

  1. Create an async component that uses useId
export default async function Component() {
  const id = useId();
  return null;
}
  1. ESLint will throw the following error:
Error: React Hook "useId" cannot be called in an async function.  react-hooks/rules-of-hooks

The current behavior

ESLint throws an error when an async component uses useId.

The expected behavior

No ESLint error.

Footnotes

  1. The documentation for React 19 does not mention it as well.

@axeleroy axeleroy added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Oct 11, 2024
@eps1lon eps1lon added Component: ESLint Rules Type: Bug and removed Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug labels Oct 11, 2024
@eps1lon eps1lon self-assigned this Oct 13, 2024
@eps1lon
Copy link
Collaborator

eps1lon commented Oct 15, 2024

Had some further discussions internally.

Or at least the documentation does not mention it1.

No Hook can be called in async Components. You can call it in a sync Component that is used in the Server environment i.e. useId can be used in shared Components.

@axeleroy
Copy link
Author

axeleroy commented Oct 15, 2024

I don't understand the logic for preventing any hooks that can run in a Server Component to be called in async components, especially for a hook as benign as useId 🤔

An explanation would be welcome, I might have missed something here.

@DamienCassou
Copy link

DamienCassou commented Oct 25, 2024

The i18next web page recommends following the guidelines in this blog post which recommends introducing an async useTranslation() hook for server components. If I understand this issue correctly, async hooks should be forbidden. Am I correct that the blog post mentioned above should not recommend an async hook?

/CC @adrai

@adrai
Copy link

adrai commented Oct 25, 2024

@DamienCassou The useTranslation hook on server side you are mentioning is not really a hook, it only has the same name as the hook on client side... theoretically you can name that async function whatever you like:

So instead of:

export async function useTranslation(lng, ns, options = {}) {
  const i18nextInstance = await initI18next(lng, ns)
  return {
    t: i18nextInstance.getFixedT(lng, Array.isArray(ns) ? ns[0] : ns, options.keyPrefix),
    i18n: i18nextInstance
  }
}
export async function getTAndI18n(lng, ns, options = {}) {
  const i18nextInstance = await initI18next(lng, ns)
  return {
    t: i18nextInstance.getFixedT(lng, Array.isArray(ns) ? ns[0] : ns, options.keyPrefix),
    i18n: i18nextInstance
  }
}

useTranslation -> getTAndI18n

@DamienCassou
Copy link

Thank you!

@eps1lon
Copy link
Collaborator

eps1lon commented Nov 4, 2024

I don't understand the logic for preventing any hooks that can run in a Server Component to be called in async components, especially for a hook as benign as useId 🤔

The implementation doesn't support this in a safe way at the moment.

@eps1lon eps1lon closed this as not planned Won't fix, can't repro, duplicate, stale Nov 4, 2024
@eps1lon eps1lon removed their assignment Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants