i18n.changeLanguage is not a function

Viewed 16468

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?

4 Answers

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

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>
   );
  }
 }

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>
  );
}

Try to use inside your onClick input events

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

This could resolve your problem.

Related