为什么使用 i18n 单击 LanguageSelector 组件中的按钮时语言没有更新?

问题描述 投票:0回答:1

我有一个使用react-i18next库支持国际化的React应用程序。 LanguageSelector 组件为每种可用语言呈现按钮,单击按钮时,它应该通过调用 i18n.changeLanguage(lng) 来更新语言。

但是,当我单击语言按钮时,似乎没有任何反应。语言不会改变,并且 onClick 处理程序中的 console.log 语句不会被打印。

我已经仔细检查了react-i18next 库是否已正确配置以及翻译是否已正确加载。应用程序的其余部分(包括主页组件)正在使用 useTranslation 挂钩来访问翻译。

我相信 LanguageSelector 组件如何集成到应用程序中或如何管理状态可能存在问题,但我似乎无法找出问题的根本原因。

您能否帮助我确定单击按钮时语言未更新的原因,并提供一些有关如何解决此问题的指导?

import { useState } from "react";
import { useTranslation } from "react-i18next";

const lngs = {
    en: { nativeLanguage: 'English' },
    it: { nativeLanguage: 'Italiano' }
};

const LanguageSelector = () => {
    const { i18n } = useTranslation();

    return (
        <div className="btn-container">
            {Object.keys(lngs).map((lng) => (
                <button
                    type="button"
                    key={lng}
                    onClick={() => {
                        console.log(`Changing language to ${lng}`);
                        i18n.changeLanguage(lng);
                    }}
                    disabled={i18n.resolvedLanguage === lng}
                >
                    {lngs[lng].nativeLanguage}
                </button>
            ))}
        </div>
    );
};

export default LanguageSelector;
// src/pages/Homepage.js

import React, {useState, useEffect, useTransition} from 'react';

import '../css/Homepage.css';
import '../css/components/MapTimeline.css';

import { sDPTFetchFactoriesFL } from '../ArcGIS.js';
import { featureLayerServiceURLs, factoryStoryMapURLs } from '../GlobalConstants.js';
import Sidebar from '../components/Sidebar.js';
import MapTimeline from '../components/TimelineMap/MapTimeline.js';
import { useTranslation } from "react-i18next";
import "../i18n.js";
import LanguageSelector from '../components/LanguageSelector.js'

function Homepage() {
    const [blurbOpacity, setBlurbOpacity] = useState(1);
    const [showScrollArrow] = useState(false);
    const [factories, setFactories] = useState([]);
    const [storymapURL, setStorymapURL] = useState('');
    const { t, i18n } = useTranslation();

    // useEffect ==> init page and get all the factories to pass to TimelineGrid when page loads
    useEffect(() => {
        // Fetch factories FL when component mounts
        sDPTFetchFactoriesFL(featureLayerServiceURLs['Factory'])
        .then(factories => {     
            setFactories(factories);
            setStorymapURL(factoryStoryMapURLs.g);
        })
        // Handle errors
        .catch(error => {
            console.error('Error fetching factories:', error);
        });
    }, []); // Empty dependency array

    // useEffect ==> blurb/title fade in and out logic
    useEffect(() => {
        
        const handleScroll = () => {
            const scrollPosition = window.scrollY;

            // Blurb fade in/out logic
            const blurbElement = document.getElementById('blurb');
            if (blurbElement) {
                const blurbHeight = blurbElement.offsetHeight;  // Get the blurb height offset
                const scrollThreshold = blurbHeight * 3;        // Threshold to start fade

                // Check the scroll position and update opacity as necessary
                if (scrollPosition < scrollThreshold) {
                    const opacity = 1 - scrollPosition / scrollThreshold;
                    setBlurbOpacity(opacity);
                } else {
                    setBlurbOpacity(0);
                }
            }
        };

        // Add an event handler to control the blur in/out  
        window.addEventListener('scroll', handleScroll);

        return () => {
            window.removeEventListener('scroll', handleScroll);
        };
    }, []);



    return (
        <div className="homepage">
            <LanguageSelector/>


            <head>
                <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
                <meta charSet="utf-8"/>
                <title>Industrial Giudecca</title>
            </head>
            {/* Sidebar div */}
            <div><Sidebar/></div>

            {/* Title div ('blurb') */}
            <div id="blurb" style={{
                opacity: blurbOpacity,
                backgroundImage: 'url("front-image.jpeg")',
                backgroundSize: '100vw 100vh',
                backgroundAttachment: 'fixed'
            }} className={blurbOpacity <= 0 ? 'fade-out' : ''}>
                {/* Contains the logos on the top of the screen */}
                <div id='logos-container'>
                    <img id='main-logo' class='logo' src='logo.png'/>
                    <img id='wpi-logo' class='logo' src='wpi-logo.png'/>
                    <img id='sdpt-logo' class='logo' src='sdpt-logo.png'/>
                </div>

                {/* Overlay to darken the homepage front image; also contains the text for the landing screen */}
                <div className='bg-overlay'>
                    <div className="blurbRow" id="blurbTop">
                        <p className="blurbElm" id="blurbTitle">{t('blurbElmBlurbTitle')}</p>
                    </div>

                    <div className="blurbRow" id="blurbBottom">
                        <p className="blurbElm" id="blurbSubtitle">{t('blurbElmBlurbSubTitle')}</p>
                        <p className="blurbElm" id="blurbCredits">- Mario Isnenghi</p>
                    </div>

                    <div className="blurbRow" id="blurbScroll">
                        <p className="blurbElm" id="scrollText">{t('blurbElmScrollText')}</p>
                        <div className={`scrollArrow ${showScrollArrow ? 'show' : ''}`}></div>
                    </div>
                </div>
            </div>

            {/* Timeline container */}
            <div id="homepage-timeline"><MapTimeline factories={factories}/></div>

            {/* Container for the section header container */}
            <div id='section-header-container' style={{
                backgroundImage: 'url("header-bg-image.jpg"',
                backgroundSize: '100% 100%',
                backgroundAttachment: 'fixed'
            }}>
                <div className='section-header-overlay' id='section-header-overlay'/>
                <div className='sb-divider'>
                    <p className='section-header'>{t("deeperDive")}</p>
                    <p className='section-header'>{t("intoIndustrialHistory")}</p>
                </div>
            </div>

            {/* Storyboard iframe from ArcGIS */}
            <iframe src="https://storymaps.arcgis.com/stories/d6072e65094c49269316d897de0cb258?cover=false" width="100%"
                    height="1050v" frameBorder="0" allowFullScreen allow="geolocation"></iframe>
        </div>
    );
}

export default Homepage;

我尝试在 LanguageSelector 文件的 onClick 部分添加控制台日志信息,但没有打印任何内容。

reactjs i18next react-i18next
1个回答
0
投票

我不认识老兄。也许尝试 git Push ?希望这对您有帮助,如果您需要更多建议,请告诉我,我也遇到了同样的问题。

© www.soinside.com 2019 - 2024. All rights reserved.