带有 React 和 Next 的语言切换器

时间:2021-03-15 19:53:46

标签: reactjs typescript internationalization i18next react-i18next

我的切换语言的想法是点击标志(点击时,标志和语言一样会改变)。到目前为止,我做得很好,标志和 url 路径也在切换,但我无法在翻译之间进行切换。

为了处理 url,我在 Next 选项 i18n 中使用构建,对于实际语言翻译,我使用 react-i18next。

我的 i18next 文件非常简单:

i18n.use(LanguageDetector)
    .use(initReactI18next)
    .init({
        resources: {
            en: {
                translation: translations_EN_homePage,
            },
            da: {
                translation: translations_DA_homePage,
            },},});

更改语言钩子和 handleOnclick 函数:

const [language, setLanguage] = useState('en');

const handleOnclick = (e) => {
    e.preventDefault();
    setLanguage(e.target.value);
    i18n.changeLanguage(e.target.value);
};

最后是我的按钮 = 标志的解决方案

                    <button
                        value={language === 'en' ? 'da' : 'en'}
                        onClick={() => {
                            const locale = router.locale === 'en' ? 'da' : 'en';
                            setCookie(locale);
                            {handleOnclick}
                            router.push(
                                `/${locale}`,
                                `/${locale}`,
                                {locale: false,}}} >
                        {router.locale === 'en' ? (
                            <img
                                src={menuItems.data.body[5].items[0].image.url}/>
                        ) : (
                            <img src={menuItems.data.body[4].items[0].image.url} />
                        )}
                    </button>

为什么 handleOnclick 函数不起作用?当我只使用 2 个按钮进行测试时,它在翻译时完全正常,那么它在哪里冲突?

我不想使用的 handleOnclick 函数的示例:

               <button value="da" onClick={handleOnclick}>
                    Danish
                </button>
                <button value="en" onClick={handleOnclick}>
                    English
                </button>

1 个答案:

答案 0 :(得分:0)

您实际上并不是在呼叫 handleOnclick。你只有 {handleOnclick} 什么都不做。您需要调用该函数。为此,您的 onClick 回调必须接受事件 e,以便它可以将其传递给 handleOnclick。您还缺少 ) 的结尾括号 router.push

这应该有效:

<button
    value={language === 'en' ? 'da' : 'en'}
    onClick={(e) => {
        const locale = router.locale === 'en' ? 'da' : 'en';
        setCookie(locale);
        handleOnclick(e);
        router.push(
            `/${locale}`,
            `/${locale}`,
            { locale: false, }
        );
    }}
>
    {router.locale === 'en' ? (
        <img src={menuItems.data.body[5].items[0].image.url} />
    ) : (
        <img src={menuItems.data.body[4].items[0].image.url} />
    )}
</button>

但是让你的一些逻辑内联和一些在一个单独的函数中是很奇怪的。我会一起移动它。

您不需要使用 e.target.value,因为 value 派生自 language。看起来您只是在两个选项之间切换。

e.preventDefault 在这里也不是真正需要的,因为按钮点击没有我们需要像链接点击或表单提交那样阻止的默认事件。

我不熟悉 react-i18next 包,所以我不知道您的 i18nrouter 变量的类型。似乎我们甚至不需要此组件中的 language 状态,因为您是从 router.locale 获取语言。

const language = router.locale ?? 'en';

const handleOnclick = () => {
    const newLang = language === 'en' ? 'da' : 'en';
    i18n.changeLanguage(newLang);
    setCookie(newLang);
    router.push( // is this correct?
        `/${newLang}`,
        `/${newLang}`,
        { locale: false, }
    );
};

return (
    <button
        onClick={handleOnclick}
    >
        {language === 'en' ? ( // you could combine some logic here
            <img src={menuItems.data.body[5].items[0].image.url} />
        ) : (
            <img src={menuItems.data.body[4].items[0].image.url} />
        )}
    </button>
)