React i18next useTranslation Hook in helper method

I’m using React with react-i18next

My index.tsx File contains some components and I can use the Translation function there

index.js

import React, { Suspense } from 'react'
import ReactDOM from 'react-dom';
import * as utils from './Utils';
import './i18n';
import { useTranslation, withTranslation, Trans } from 'react-i18next';

...
  const { t, i18n } = useTranslation();
  //I can use the translate function here
  t("title");
  //call a util function
  utils.helperFunction(...);
...

Everything works fine here.
I now created some helper functions in an additional file

Utils.tsx

...
import { useTranslation, withTranslation, Trans } from 'react-i18next';
...
export function helperFunction(props: any){
   //do stuff

   //now I need some translation here - but useTranslation is not working?
   const { t, i18n } = useTranslation();
   t("needTranslation");
}

How can I use the same translation logic inside my helper function? (without always passing the t function to the helper-method)

Or is the usage of the hook the wrong approach here?

The following error occurs

React Hook "useTranslation" is called in function "helperFunction" which is neither a React function component or a custom React Hook function  react-hooks/rules-of-hooks

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I fixed my issue by not using the useTranslation hook anymore

Instead I moved the i18n initalizitation to a file (i18n.tsx – exports i18n)
and import and use it in my Utils class

My Utils.tsx file now looks like this

Utils.tsx

...
import i18n from '../i18n';
...
export function helperFunction(props: any){
   //do stuff

   //use imported i18n and call the t() method
   i18n.t("needTranslation");
}

i18n.tsx

import i18n from "i18next";
import Backend from 'i18next-xhr-backend';
import { initReactI18next } from 'react-i18next';

i18n
  .use(Backend) 
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    lng: "es",
    fallbackLng: 'en',
    backend: {
      loadPath: '/static/locales/{{lng}}/{{ns}}.json'
    },    
    interpolation: {
      escapeValue: false
    }
  });

  export default i18n;

Method 2

It looks like you forgot a quote t("needTranslation); -> t("needTranslation");

After I ran your code I see why your code isn’t working. If you want to extract component logic into reusable functions, then you should make a custom hook. For more info look at the docs.

import React from "react";
import ReactDOM from "react-dom";
import i18n from "i18next";
import "./i18n.js";
import { useTranslation, initReactI18next } from "react-i18next";

i18n
  .use(initReactI18next) 
  .init({
    resources: {
      en: {
        translation: {
          title: "Hello world",
          subtitle: "Hello stackoverflow"
        }
      }
    },
    lng: "en",
    fallbackLng: "en",

    interpolation: {
      escapeValue: false
    }
  });

function App() {
  const { t } = useTranslation();
  useHelperFunction();
  return <h1>{t("title")}</h1>;
}

// you need to turn the helper function into a hook
function useHelperFunction() {
  const { t } = useTranslation();
  return <h2>{t("subtitle")}</h2>;
}

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x