Error: Uncaught [Error: `useI18n` must be used inside `I18nProvider`]

See original GitHub issue

Hello, thank you for this awesome library I’m using this package with Jest and it doesn’t seems to work properly

this is my customRender.tsx

import en from 'locales/en';
import { ThemeProvider } from '@mui/material';
import { theme } from 'styles/theme';
import { render, cleanup } from '@testing-library/react';
import { createI18n } from 'next-international';

// I tried different methods to mock next/router
// 1. first attempt
const useRouter = jest.spyOn(require('next/router'), 'useRouter');
useRouter.mockImplementationOnce(() => ({
    locale: 'en',
    defaultLocale: 'en',
    locales: ['en', 'fr'],
}));

// 2. second attempt
jest.mock('next/router', () => ({
  useRouter: () => ({
    locale: 'en',
    defaultLocale: 'en',
    locales: ['en', 'fr'],
  }),
}));

afterEach(() => {
    cleanup()
})

const { I18nProvider } = createI18n<typeof en>({
    en: () => import('locales/en'),
    fr: () => import('locales/fr'),
})

const Providers = ({ children }: { children: any }) => {
    return <I18nProvider locale={en}><ThemeProvider theme={theme}>{children}</ThemeProvider></I18nProvider>
};
const customRender = (ui: any, options = {}) => render(ui, { wrapper: Providers, ...options });
export * from '@testing-library/react';
export { default as userEvent } from '@testing-library/user-event'
export { customRender as render };

I have a component where I use i18n and the test fail all the time

import { cleanup, fireEvent } from '@testing-library/react';
import { render, screen } from 'testing/customRender'

import React from 'react';
import InputField from '.';

afterEach(cleanup);

describe('<InputField />', () => {
    it('handleChange function called', () => {
        const spy = jest.fn();
        render(<InputField field={{ name: 'text', onChange: spy }} label="nom" />);
        let input = screen.getByLabelText('nom') as HTMLInputElement;
        expect(input.value).toBe('');

        fireEvent.change(input, { target: { value: '23' } });
        fireEvent.blur(input, { target: { value: '23' } });
        expect(spy).toHaveBeenCalledTimes(1);
    });
});
// locales.ts
import { createI18n } from 'next-international';
import type Locale from './en';
export const { useI18n, I18nProvider, useChangeLocale, defineLocale, getLocaleProps } = createI18n<typeof Locale>({
  en: () => import('./en'),
  fr: () => import('./fr'),
});

Inside my component I import the hook use18n() from locales const { t } = useI18n();

When I run my tests I get the following error

TypeError: Cannot destructure property 'locale' of '(0 , B.useRouter)(...)' as it is null.

Can you please provide an example with jest? a wrapper and how to use it inside a component that uses i18n

Thank you so much

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
chaosLegacycommented, Oct 21, 2022

Thank you so much for your help You are a life saver 🙏

0reactions
QuiiBzcommented, Oct 21, 2022

Great! About the warning, make sure the locales array inside the next/router mock matches the keys of createI18n().

Is there a way to add this in the wrapper instead of repeating it in every test file?

I think you can use setupFilesAfterEnv and include the mock of next/router in it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Problem to use VueI18n outside a component - Stack Overflow
To use i18n with Vue 3's composition API, but outside a ... { t } = useI18n() // Uncaught SyntaxError: Must be called...
Read more >
React Hooks support · Issue #390 · lingui/js-lingui - GitHub
At this point, should I use useI18n hook or the Trans component from @lingui/macro , they both will utilize the same i18n instance,...
Read more >
i18n - npm
Lightweight simple translation module with dynamic JSON storage. Supports plain vanilla Node.js apps and should work with any framework (like ...
Read more >
Composition API - Vue I18n
You must call useI18n at top of the setup . The useI18n returns a Composer instance. The Composer instance provides a translation API...
Read more >
Tutorial - Internationalization of React apps - LinguiJS - JS.ORG
Let's add all required imports and wrap our app inside <I18nProvider>: // src/index.js import React from 'react' import { render } from 'react-dom'...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found