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

Issue with <I18nProviderClient> and ref Access to DOM Node #439

Open
PH-LEE opened this issue Jan 7, 2025 · 0 comments
Open

Issue with <I18nProviderClient> and ref Access to DOM Node #439

PH-LEE opened this issue Jan 7, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@PH-LEE
Copy link

PH-LEE commented Jan 7, 2025

Describe the bug
I am unsure whether this is a bug or expected behavior.
The placement of the 18nProviderClient wrapper seems to affect whether the ref can correctly access the DOM node.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://stackblitz.com/edit/stackblitz-starters-ypqqpfsf
  2. Click the layout wrapper link
  3. The ref can access the input DOM (autofocus works as expected)
  4. Click the Reload page button
  5. Click the component wrapper link
  6. The ref cannot access the input DOM (no autofocus, ref.current is null)

Expected behavior
The placement of I18nProviderClient should not affect access to the DOM node.

About:
package.json:

  • "next": "^15.1.3",
  • "next-international": "^1.3.1",
  • "react": "^19.0.0",
  • "react-dom": "^19.0.0",

Additional context
reproduce link: https://stackblitz.com/edit/stackblitz-starters-ypqqpfsf

app/[locale]/layout-wrapper/layout.tsx

import { ReactElement } from 'react'
import { I18nProviderClient } from '/locales/client'
 
export default async function SubLayout({ params, children }: { params: Promise<{ locale: string }>, children: ReactElement }) {
  const { locale } = await params
 
  return (
    <I18nProviderClient locale={locale}>
      {children}
    </I18nProviderClient>
  )
}

LayoutWrapper.tsx

'use client';
import { forwardRef, useEffect, useRef } from 'react';
import { useI18n } from '/locales/client';

function useInputRef() {
  const inputRef = useRef<HTMLInputElement | null>(null);
  useFocus(inputRef);

  return { inputRef };
}

function useFocus(ref: React.RefObject<HTMLInputElement | null>) {
  useEffect(() => {
    console.log(ref.current);
    if (ref.current) {
      ref.current.focus();
    }
  }, [ref]);
}

const ForWardRefInput = forwardRef(function ForWardRefInput(
  _,
  ref: React.ForwardedRef<HTMLInputElement | null>
) {
  return <input type="text" className="border-2" ref={ref} />;
});

const DivWithInput = forwardRef(function DivWithInput(
  _,
  ref: React.ForwardedRef<HTMLInputElement | null>
) {
  const t = useI18n();
  return (
    <div className="m-8 flex flex-col gap-2">
      <h1>{t('hello')}</h1>
      <ForWardRefInput ref={ref} />
    </div>
  );
});

export default function LayoutWrapper() {
  const { inputRef } = useInputRef();
  return (
    <>
      <button onClick={() => (window.location.href = '/')}>Reload page</button>
      <DivWithInput ref={inputRef} />
    </>
  );
}

ComponentWrapper.tsx

'use client';
import { forwardRef, useEffect, useRef } from 'react';
import { I18nProviderClient, useI18n } from '/locales/client';

function useInputRef() {
  const inputRef = useRef<HTMLInputElement | null>(null);
  useFocus(inputRef);

  return { inputRef };
}

function useFocus(ref: React.RefObject<HTMLInputElement | null>) {
  useEffect(() => {
    console.log(ref.current);
    if (ref.current) {
      ref.current.focus();
    }
  }, [ref]);
}

const ForWardRefInput = forwardRef(function ForWardRefInput(
  _,
  ref: React.ForwardedRef<HTMLInputElement | null>
) {
  return <input type="text" className="border-2" ref={ref} />;
});

const DivWithInput = forwardRef(function DivWithInput(
  _,
  ref: React.ForwardedRef<HTMLInputElement | null>
) {
  const t = useI18n();
  return (
    <div className="m-8 flex flex-col gap-2">
      <h1>{t('hello')}</h1>
      <ForWardRefInput ref={ref} />
    </div>
  );
});

export default function ComponentWrapper({ locale }: { locale: string }) {
  const { inputRef } = useInputRef();
  return (
    <>
      <button onClick={() => (window.location.href = '/')}>Reload page</button>
      <I18nProviderClient locale={locale}>
        <DivWithInput ref={inputRef} />
      </I18nProviderClient>
    </>
  );
}

@PH-LEE PH-LEE added the bug Something isn't working label Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant