LaFllamme
LaFllamme

Reputation: 288

Use imported function in return method (invalid hook call, react js)

Wassup Guys,

I have a reusable component, that translates keys into a choosen language through keynames as string or a binded var.

Usually I use a tag for this, but because of different reasons I am switching/replacing current translations with {t('...')}.

Here is the code of the component:

import React from 'react';
import { useTranslation as defaultTranslation } from 'react-i18next';
import i18next from 'i18next';

export const useTranslation = (ns = 'common', options) => {
  return defaultTranslation(ns, {
    useSuspense: false,
    ...options,
  });
};

export const withTranslation = (Component, ns, options) => {
  const TranslatedHOC = (props) => {
    const translationProps = useTranslation(ns, options);

    return <Component {...translationProps} {...props} />;
  };
  return TranslatedHOC;
};

export const getCurrentLanguage = () =>
  i18next.language || localStorage.getItem('language') || 'de-DE';

First of all I define the const for the used imported function:

const {t} = useTranslation();

normal case: importing my component in the file, where I want to use it and add code above.

Code of my component, where I want to replace the Tags.


// Import React Table
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import LocalizedText from '@components/i18n/LocalizedText';

class T extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      pages: null,
      loading: true,
    };
    this.fetchData = this.fetchData.bind(this);
  }
  fetchData(state, instance) {
    this.props.onFetchData(state, instance).then(() => {
      this.setState({
        loading: false,
      });
    });
  }
  render() {
    return (
      <ReactTable
        {...this.props}
        previousText={
          <LocalizedText textKey="caseoverview.orderproduct.back" />
        }
        nextText={
          <LocalizedText textKey="caseoverview.orderproduct.continue" />
        }
        loadingText={<LocalizedText textKey="loading" />}
        noDataText={<LocalizedText textKey="placeholders.nodata" />}
        pageText={
          <LocalizedText textKey="reservationcalculator.search.result.page" />
        }
        ofText={<LocalizedText textKey="from" />}
        rowsText={<LocalizedText textKey="rows" />}
        className="case-search-table"
      />
    );
  }
}

export default T;
...
   previousText={
          <LocalizedText textKey="caseoverview.orderproduct.back" />
        }
...

should change to:

...
   previousText={
          t('caseoverview.orderproduct.back')
        }
...

The problem is, that I can't use the code quoted above without getting any issues regarding invalid hook calls. If I move it out somehow, I get errors telling me that my 't' is either not defined or an unexpected token. Could someone help me out? Searched online for solutios without any result.

Upvotes: 0

Views: 139

Answers (2)

LaFllamme
LaFllamme

Reputation: 288

@kevin asworth answer helped me out. Using withTranslation with passing t as prop

const {t} = this.props;

inside the render method worked for me.

Upvotes: 0

Kevin Ashworth
Kevin Ashworth

Reputation: 643

A hook can only be used in a functional component. You can change this class component to a functional component, or you can use react-i18next's withTranslation HOC to wrap your class component. See https://react.i18next.com/latest/withtranslation-hoc#when-to-use

Upvotes: 1

Related Questions