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

t function from useTranslation is unstable in concurrent mode #1691

Closed
woodreamz opened this issue Oct 31, 2023 · 13 comments · Fixed by #1716
Closed

t function from useTranslation is unstable in concurrent mode #1691

woodreamz opened this issue Oct 31, 2023 · 13 comments · Fixed by #1716

Comments

@woodreamz
Copy link

woodreamz commented Oct 31, 2023

🐛 Bug Report

The bug is really well explained in #1599. This issue has been also reported in #1636. Those issues have been closed without being fixed.

When enabling concurrent mode in React, the t function changes and creates extra renders. i18n.t is not doing that. For now, it's not major as concurrent mode is not enabled in production build but could become major in a futur react release.

The issue seems to be in useTranslation. I am trying to find a fix and propose a PR. This issue will help to track the work.

For now, concurrent mode is enabled with StrictMode.

You can use to help surface concurrency-related bugs during development. Strict Mode doesn’t affect production behavior, but during development it will log extra warnings and double-invoke functions that are expected to be idempotent.
Source: react.dev

To Reproduce

In this codesandbox, you can se in the console that the useEffect on i18n is called 2 times and the useEffect on t is called 3 times.

import "./i18next";
import { useTranslation } from "react-i18next";
import { useEffect } from "react";

export default function App() {
  const { i18n, t } = useTranslation();

  useEffect(() => {
    console.log("useEffect with i18n");
  }, [i18n]);

  useEffect(() => {
    console.log("useEffect with t");
  }, [t]);

  return i18n.t("text");
}

Expected behavior

useEffect with t as dependency should be called 2 times.

@woodreamz
Copy link
Author

It seems to be caused by:

@qq831799
Copy link

Same issue here, and my react-i18next version is 12.3.1

@timheilman
Copy link
Contributor

same issue here. Thank you @woodreamz for your sleuthing so far.

@adrai
Copy link
Member

adrai commented Feb 1, 2024

It seems to be caused by:

was introduced here by @medihack because of this

@timheilman
Copy link
Contributor

I have a draft PR to fix this at #1716 ; still working through the contribution checklist.
I'm not sure hook-based testing including strictMode is yet available; I've found this, which was just merged:

testing-library/react-testing-library#1241

but I haven't looked into hook-testing support using it, yet

@adrai
Copy link
Member

adrai commented Feb 4, 2024

Should be fixed with v14.0.2

@timheilman
Copy link
Contributor

Thank you @woodreamz for generating a minimal reproduction of the bug and @adrai for maintaining this repo and providing me the opportunity to contribute :)

@adrai
Copy link
Member

adrai commented Feb 5, 2024

reverted with v14.0.3 and waiting for a better fix... because of this

@adrai adrai reopened this Feb 5, 2024
@timheilman
Copy link
Contributor

Sorry for the false start! I hope #1720 will be better forward progress.

@adrai
Copy link
Member

adrai commented Feb 6, 2024

should be addressed with v14.0.5

@adrai adrai closed this as completed Feb 6, 2024
@wr-lhiggitt
Copy link

This is still occurring for me in 14.0.5

@timheilman
Copy link
Contributor

I'm afraid I can reliably reproduce using the minimal reproduction from the original post in 14.0.3, and I cannot reproduce using 14.0.5 . I'm still interested in the bug; are you able to see the bug using the reproduction in the original post? If not, can you provide a different minimal reproduction with expected result vs actual result?

@MarlonVCendron
Copy link

I don't know if that's related or not. But having t as a dependency on useMemo makes it render indefinetely, but as a dependency on useEffect it works normally. This only happens in a specific component, I wasn't able to create a minimal reproduction of the bug, so maybe it's just something I'm doing wrong, but can't figure it out.

const tools = useMemo(() => {
    console.log('useMemo')
    return []
  }, [t])

  useEffect(() => {
    console.log('useEffect')
  }, [t])
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants