i18next / next-app-dir-i18next-example

Next.js 13/14 app directory feature in combination with i18next
https://locize.com/blog/next-app-dir-i18n/
175 stars 36 forks source link

Cannot update a component (`Footer`) while rendering a different component (`Page`) (Update: Minified React error #425/418;) #9

Closed dejurin closed 1 year ago

dejurin commented 1 year ago

🐛 Bug Report

Warning: Cannot update a component (Footer) while rendering a different component (Page). To locate the bad setState() call inside Page

To Reproduce

ezgif com-gif-maker

In this example "client side", if we switch languages, we will get an error.

Apparently, this is due to the fact that we are loading the state again.

export function useTranslation(lng, ns, options) {
  if (i18next.resolvedLanguage !== lng) i18next.changeLanguage(lng)
  return useTranslationOrg(ns, options)
}

UPDATE I continued to research and found "Minified React error" see below.

Screenshot 2023-01-22 at 22 10 49

This error occurs after the build at startup if you go to the client side and reload the page. The problem with this error is that the client side freezes; I think this is a consequence of what I wrote earlier; The problem disappears if you remove the useTranslation hook.

Unfortunately, it is not possible to use this in production, you need to study the problem and look for a solution.

Uncaught Error: Minified React error #425; visit https://reactjs.org/docs/error-decoder.html?invariant=425 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Uncaught Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Your Environment

adrai commented 1 year ago

It's just a warning... Do you know of a working alternative?

dejurin commented 1 year ago

It's just a warning... Do you know of a working alternative?

Not yet. I just discovered.

dejurin commented 1 year ago

Update. Look up.

adrai commented 1 year ago

Sorry, I have no idea.... but fyi: on production I don't see any error at all.

dejurin commented 1 year ago

Sorry, I have no idea.... but fyi: on production I don't see any error at all.

It does not appear immediately, but after reloading the page (CMD+R), I still cannot find a pattern for its appearance. I'll try to record a video.

maxsilvauk commented 1 year ago

Is this still an error for you?

dejurin commented 1 year ago

Is this still an error for you?

yep, but I think this error is nextjs

mertafor commented 1 year ago

I'm having the same problem. However it doesn't happen on the first load or switching the language. Only happens when I get back to first language. I use the same language switcher methods, Link. For example default language is "fr". I switch to "en" and it works without an error. But if I click to "fr" again to switch back, I see this error in console. In dev mode by the way.

Tried on nextjs 13.3.4 and 13.4 (just released)

adrai commented 1 year ago

@mertafor are you able to reproduce it with this example? I'm not able to see that issue.

mertafor commented 1 year ago

@adrai It's my bad. I've been using the example structure provided at https://locize.com/blog/next-13-app-dir-i18n/ . I'll try this one and let you know. Thanks

mertafor commented 1 year ago

Now I cloned this repo and tried the same action, switching between languages back and forth on client-side page throws the same warning.

It doesn't break the script yet it seems like a loop caused by18next.changeLanguage :

export function useTranslation(lng, ns, options) {
  if (i18next.resolvedLanguage !== lng) i18next.changeLanguage(lng)
  return useTranslationOrg(ns, options)
}

Here is the warning :

Warning: Cannot update a component (`Footer`) while rendering a different component (`Page`). To locate the bad setState() call inside `Page`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at Page (webpack-internal:///(app-client)/./app/[lng]/client-page/page.js:21:19)
    at StaticGenerationSearchParamsBailoutProvider (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/static-generation-searchparams-bailout-provider.js:15:11)
    at InnerLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:225:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:40:11)
    at LoadingBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:330:11)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at ScrollAndFocusHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:211:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at OuterLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:340:11)
    at InnerLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:225:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:40:11)
    at LoadingBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:330:11)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at ScrollAndFocusHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:211:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at OuterLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:340:11)
    at body
    at html
    at InnerLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:225:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:40:11)
    at LoadingBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:330:11)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at ScrollAndFocusHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:211:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at OuterLayoutRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/layout-router.js:340:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
    at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:40:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at HotReload (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:276:11)
    at Router (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:90:11)
    at commitLayoutEffectOnFiber (webpack-internal:///(app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:20290:9)
    at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
    at AppRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:372:13)
    at ServerRoot (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:154:11)
    at RSCComponent
    at Root (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:171:11)
adrai commented 1 year ago

@mertafor sorry, no idea how to prevent that warning... seems the Footer in that case gets a stale lng to change language to... but only a warning... so not that critical, right?

vietcuongk99 commented 1 year ago

I follow your guide in blog, when i deploy my web to production, i found that some component of my page was not translated after first switched language. I use Nextjs v13.4.1

codehwl commented 1 year ago

In the file i18n/client.js, I attempted to modify the code as follows, and it works well without any warnings:

import { useEffect } from 'react'

// some other code...

// fix useTranslation
export function useTranslation(lng, ns, options) {
  useEffect(() => {
    if (i18next.resolvedLanguage !== lng) i18next.changeLanguage(lng)
  }, [lng])
  return useTranslationOrg(ns, options)
}
vietcuongk99 commented 1 year ago

it seem like set useEffect inside useTranslation function cause client component not translated correctly

adrai commented 1 year ago

it seem like set useEffect inside useTranslation function cause client component not translated correctly

@vietcuongk99 can you provide more info please?

vietcuongk99 commented 1 year ago

yes, so i have two language: vi and en. I set vi as default locale

this is my page.js render as main route, i set it as server component, you can see Header component (client component), Header receive lng from page.js as prop image

inside Header, i use that useTranslation function to translate for client component image

This is my result. After i clicked England flag, i change route from /vi to /en image

You can see that content below Header is translated, this is belong to page.js that i mentioned, but content from Header still not translated

I hope this is enough infor. Or maybe i make mistake somewhere in my code ?

adrai commented 1 year ago

@vietcuongk99 please provide a minimal reproducible example repository, so we can investigate.

vyach-g commented 1 year ago

@adrai using useEffect in useTranslation hook affects the translation of client pages. Just run this repos example and open client page directly by url. First it opens in the default language, then flickers and translates to the desired language, because of this we also have hydration errors. If we remove useEffect (like it was before 03f2917 commit) it works properly

https://github.com/i18next/next-13-app-dir-i18next-example/assets/96015895/2cb32cd9-0aab-414e-ab16-7e0cb49f6d3f

adrai commented 1 year ago

@vyach-g try this: https://github.com/i18next/next-13-app-dir-i18next-example/commit/25f0658ab2c2790bd346afa0bd24aa644ab03fe5

vyach-g commented 1 year ago

@adrai yep, thanks, it seems to work fine

vietcuongk99 commented 1 year ago

@adrai it seem like i mess up with my next.config.js. After carefully follow your guide and apply 25f0658, i solve my problem. Thank you