user12145676
user12145676

Reputation:

i18n.changeLanguage is not a function

This is my code.

import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';

function Page() {
  const { t, i18n } = useTranslation();

  const changeLanguage = lng => {
    i18n.changeLanguage(lng);
  };

  return (
    <div className="App">
      <div className="App-header">
        <button onClick={() => changeLanguage('de')}>de</button>
        <button onClick={() => changeLanguage('en')}>en</button>
      </div>
      <div>{t('test')}</div>
    </div>
  );
}

export default function App() {
  return (
    <Suspense fallback={<div>loading...</div>}>
      <Page />
    </Suspense>
  );
}

when I click on the de en button. I get this error. TypeError: i18n.changeLanguage is not a function.How to fix?

Upvotes: 15

Views: 35809

Answers (6)

Tigran Muradyan
Tigran Muradyan

Reputation: 123

Below steps fixed the problem for me:

  • Be sure that i18n.js is created with similar code:
import i18n from "i18next";
import Backend from "i18next-xhr-backend";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    debug: true,
    resources: {
      en: {
        translation: {
          greeting: "Hello",
        },
      },
      fr: {
        translation: {
          greeting: "Bonjour",
        },
      },
    },
    interpolation: {
      escapeValue: false,
    },
  });

export default i18n;
  • Import in index.tsx or index.js file:
import "./i18n";
  • Use it with an existing hook:
const { t, i18n } = useTranslation();

Feel free to comment if there is an issue still there.

Upvotes: 0

Taiwan No.1
Taiwan No.1

Reputation: 413

It was not a config problem. What you need to do was to add

import "./util/i18n";

in your App.tsx and rebuild your project, ie run npm run start again.

Upvotes: 0

Igor Zvyagin
Igor Zvyagin

Reputation: 474

I had same error. Unfortunately the i18n documentation is not very good.

We need to create the i18n provider (I18nextProvider) and pass it an i18n object after calling the init function. Of course, we have to wrap our App in I18nextProvider

i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './en.json';
import de from './de.json';

i18n
  .use(initReactI18next)
  .init({
    resources: {
      en: {
        translation: en,
      },
      de: {
        translation: de,
      },
    },
    fallbackLng: 'en',
    interpolation: {
      escapeValue: false,
    },
  });

export default i18n;

index.js

import React from 'react';
import { useTranslation, I18nextProvider } from 'react-i18next';
import i18n from './i18n';

function Page() {
  const { t, i18n } = useTranslation();

  const changeLanguage = lng => {
    i18n.changeLanguage(lng);
  };

  return (
    <div className="App">
      <div className="App-header">
        <button onClick={() => changeLanguage('de')}>de</button>
        <button onClick={() => changeLanguage('en')}>en</button>
      </div>
      <div>{t('test')}</div>
    </div>
  );
}

export default function App() {
  return (
    <I18nextProvider i18n={i18n}>
      <Page />
    </I18nextProvider>
  );
}

Upvotes: 6

Fausta
Fausta

Reputation: 72

a) move changeLanguage like in the code above - but also import i18n from '../i18n'; or where you defined your i18n instance.

import i18n from 'i18n';

// define the function outside of component scope
const changeLanguage = (lng) => {
  i18n.changeLanguage(lng);
};

b) Or following steps:

import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';

function Page() {
  const { t, i18n } = useTranslation();

  const toggle = lng => i18n.changeLanguage(lng); 
  if (this.props.event){

   return (
    <div className="App">
      <div className="App-header">
        <button onClick={() => toggle(this.props.event)}>de</button>
        <button onClick={() => toggle(this.props.event)}>en</button>
      </div>
      <div>{t('test')}</div>
    </div>
   );
  }
 }

Upvotes: 4

Hamza El Aoutar
Hamza El Aoutar

Reputation: 5647

Looks like you haven't configured i18next.

You will need to create a file i18n.js containing the following content:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import Backend from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';


i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: true,

    interpolation: {
      escapeValue: false,
    }
  });
export default i18n;

Then import it in your index.js:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import App from './App';

import './i18n';

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

source

Upvotes: 28

Try to use inside your onClick input events

() => changeLanguage('en').bind(this)

This could resolve your problem.

Upvotes: -2

Related Questions