React Native - 带有反应导航和打字稿的 I18Next

时间:2021-05-27 09:30:29

标签: react-native react-redux i18next react-i18next

我开始了这个 RN 项目。我需要在其中进行本地化,为此我尝试了多种解决方案。 I18Next 看起来非常适合我的需求。我不确定如何在它自己的文件中定义它并在 App.tsx 中调用它。我使用了 useEffect 但我怀疑它是否明智 - 甚至没有任何依赖项。这是我尝试过的:

i18n.ts:

import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import * as Localization from 'expo-localization';
import en from './en.json';
import fr from './fr.json';

const resources = {en: { translation: en }, fr: { translation: fr }};

i18next
  // .use(languageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: true,
    resources,
    lng: Localization.locale.slice(0, 2),
  });

export default i18next;

以及 App.tsx 中的代码:

// ...
import i18next from './src/locales/i18n';

export default function App(): React.ReactElement {
  useEffect(() => {
    i18next
      .init()
      .then(() => {
        // TODO - dispatch to redux when this is ready
      })
      .catch(error => console.warn(error));
  });

  return (
    <Provider store={store}>
      <PersistGate loading={<SplashScreen />} persistor={persistor}>
        <StatusBar hidden />
        <MainNavigation />
      </PersistGate>
    </Provider>
  );
}

我收到警告 i18next: init: i18next is already initialized. You should call init just once!。确实,我在主文件中调用了两次 .init(),然后在 useEffect 中再次调用了 useEffect。但我不知道该怎么做。

另外,我的You will only need to use the provider in scenarios for SSR (ServerSideRendering) or if you need to support multiple i18next instances - eg. if you provide a component library.还好吗?

[编辑] 我在文档中找到了 https://react.i18next.com/latest/i18nextprovider 并使用它并删除了 useEffect,警告消失了 - 尽管我不确定这是否是一个好主意,因为文档指出 {{1}}< /p>

1 个答案:

答案 0 :(得分:0)

实际上我只需要初始化一次,也不需要使用提供程序。终于搞定了:

const onBeforeLift = async () => {
  await initI18Next();
};

export default function App(): React.ReactElement {
  return (
    <Provider store={store}>
      <PersistGate
        loading={<SplashScreen />}
        persistor={persistor}
        onBeforeLift={onBeforeLift}
      >
        <StatusBar hidden />
        <MainNavigation />
      </PersistGate>
    </Provider>
  );
}

i18n.ts中:

const resources = {
  en: { translation: en },
  fr: { translation: fr },
  he: { translation: he },
};

export const init = () => {
  const lng = store.getState().user.language
    ? store.getState().user.language
    : Localization.locale.slice(0, 2);

  return (
    i18next
      .use(initReactI18next)
      .init({
        fallbackLng: 'en',
        debug: true,
        resources,
        lng,
      })
  );
};

export default i18next;