Skip to content
Advertisement

React – Invalid hook call when calling useTranslation for react-i18next

I’m new to React Native and I’m trying to add translation in my navigation. In any other page it goes fine but not in my navigation.

My i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import storage from '../app/services/storage';
import { USER_LANG, getDeviceLang } from './utils';

/** Localization */
import en from './en.json';
import es from './es.json';
import no from './no.json';
/** Localization */

/*---------------------------------
          LANGUAGE DETECTOR
---------------------------------*/
const languageDetector = {
  init: Function.prototype,
  type: 'languageDetector',
  async: true, // flags below detection to be async
  detect: async (callback) => {
    const userLang = await storage.get(USER_LANG);

    const deviceLang = userLang || getDeviceLang();
    //RNRestart.Restart();
    callback(deviceLang);
  },
  cacheUserLanguage: () => { },
};

/*---------------------------------
            I18N CONFIG
---------------------------------*/
i18n
  .use(languageDetector)
  .use(initReactI18next)
  .init({
    compatibilityJSON: 'v3',
    fallbackLng: 'en',
    resources: {
      en,
      es,
      no,
    },
    // have a common namespace used around the full app
    ns: ['translation'],
    defaultNS: 'translation',

    debug: true,

    //   cache: {
    //  enabled: true
    // },

    interpolation: {
      escapeValue: false,
    },
    react: {
      useSuspense: false,
    }
  });

export default i18n;

My StackNavigators.js

import React, { useState, useEffect } from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Keyboard } from 'react-native';
import TodayRates from '../pages/todayrates';
import Dashboard from '../pages/dashboard';
import UserService from '../services/userService';
import Profile from '../pages/profile';
import TodayActivities from '../pages/todayActivities';
import Tasks from '../pages/tasks';
import Task from '../pages/task';
import Settings from '../pages/settings';
import { BottomNavigation, BottomNavigationTab } from '@ui-kitten/components';
import { CreateTaskIcon } from '../assets/icons';

// For translation
import '../../i18n/i18n';
import { useTranslation } from 'react-i18next';
const { t, i18n } = useTranslation(); //<-- This is the issue and not sure where to add

const { Navigator, Screen } = createBottomTabNavigator();

const BottomTabBar = ({ navigation, state }) => (
    <BottomNavigation>
        <BottomNavigationTab title='Dashboard'/>
        <BottomNavigationTab title='Activities' />
        <BottomNavigationTab
            icon={<CreateTaskIcon fill="#fff" width={30} height={30} />}
        />
        <BottomNavigationTab title='Tasks' />
        <BottomNavigationTab title='Rates' />
    </BottomNavigation>
);

const StackNavigators = () => {
    const [user, setUser] = useState({});
    const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);
    const getUser = async () => {
        await UserService.getCurrentUser().then((user) => {
            setUser(user);
        })
    }

    useEffect(() => {
        getUser();

        const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
            setIsKeyboardVisible(true);
        });
        const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
            setIsKeyboardVisible(false);
        });
    
        return () => {
            showSubscription.remove();
            hideSubscription.remove();
        };
    }, [isKeyboardVisible]);

    const getVisibilityStyle = (keyboardVisibility, props) => {
        if (!keyboardVisibility){
            return <BottomTabBar {...props}/>;
        }
        return null;
    }

    return (
        <Navigator
            initialRouteName="Dashboard"
            tabBar={
                props => getVisibilityStyle(isKeyboardVisible, props)
            }>
            <Screen name="Dashboard" component={Dashboard} options={{ headerShown: false }} />
            <Screen name="Activities" initialParams={{ user: user }} component={TodayActivities} options={{ headerShown: false }} />
            <Screen name="+" component={Task} options={{ unmountOnBlur: true, headerShown: false }} />
            <Screen name="Tasks" component={Tasks} options={{ unmountOnBlur: true, headerShown: false }} />
            <Screen name="TodayRates" initialParams={{ user: user }} component={TodayRates} options={{ unmountOnBlur: true, headerShown: false }} />
            <Screen name="Profile" component={Profile} options={{ headerShown: false }} />
            <Screen name="Settings" component={Settings} options={{ headerShown: false }} />
            <Screen name="EditTask" component={Task} options={{ unmountOnBlur: true, headerShown: false }} />
        </Navigator>
    );
}

export default StackNavigators;

What I’m trying to do is to add translation in BottomTabBar as title of each BottomNavigationTab and when I add const { t, i18n } = useTranslation(); I get Invalid hook call and I’m not sure what would the correct place/way be.

Appreciate any help and thanks in advance!

Advertisement

Answer

You cannot call a hook outside of a React component or hook (see Rules of Hooks). Move this line const { t, i18n } = useTranslation(); inside BottomTabBar component. Like so:

const BottomTabBar = ({ navigation, state }) => {
    const { t, i18n } = useTranslation();
    return(
     <BottomNavigation>
        <BottomNavigationTab title='Dashboard'/>
        <BottomNavigationTab title='Activities' />
        <BottomNavigationTab
            icon={<CreateTaskIcon fill="#fff" width={30} height={30} />}
        />
        <BottomNavigationTab title='Tasks' />
        <BottomNavigationTab title='Rates' />
     </BottomNavigation>)
};
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement