skip to Main Content

I would like the wording used for the layout inside mainPage would change according to the language selected at component Header.jsx. However, change in Header.jsx could not pass to Header.jsx, therefore, noting is changed when clicking on the language selector.

import React, { useState, useEffect } from "react";
import Header from "../Resources/Components/Header";
import Footer from "../Resources/Components/Footer";
import {MainPageContext, useMainPageContext } from "../Resources/Hooks/mainPageContext";

import "./MainPage.css";

const MainPage = () => {

const context = useMainPageContext();
const {
  language,
} = context;

useEffect(()=>{
  console.log("is me hi!")
},[language])

  const [introductionPage, setIntroductionPage] = useState(0);
  console.log("language is", language)
  //const [language, setLanguage]= useState(0);

  //below is the script of the test description. 隨時可以加入新array做新language。
  const renderLanguageSwitch= (language) => {
    switch(language) {
      case 0:
        return ['測試開始','測試資料採集同意書'];
      case 1:
        return ['Test Start', 'Test Data Collection Agreement']
      default:
        return ['測試開始','測試資料採集同意書'];
    }
  };

  const renderButtonSwitch= (language) => {
    switch(language) {
      case 0:
        return ['我同意', '我拒絕'];
      case 1:
        return ['I agree', 'I disagree']
      default:
        return ['我同意', '我拒絕'];
    }
  };

  return (
    <div className="MainPage">
      <Header />
      <div
        style={{
          width: "100%",
          height: "100vh",
          backgroundColor: "#F5821F",
          margin: "0",
        }}
      >
        {introductionPage === 0 && (
          <button
            className="testStartBox"
            onClick={() => {
              setIntroductionPage(1);
            }}
          >
            {renderLanguageSwitch(language)[0]}
          </button>
        )}
        {introductionPage !== 0 && (
          <div>
          <div
            className="testDescriptionBox"
            onClick={() => {
              setIntroductionPage(introductionPage + 1);
            }}
          >
             {renderLanguageSwitch(language)[1]}
          </div>
          <div className="testAgreement">

          </div>
          </div>
        )}

        <div
          className="buttonWrapper"
          style={{ display: introductionPage === 1 ? "" : "none" }}
        >
          <button  onClick={() => {
              setIntroductionPage(introductionPage + 1);
            }}> {renderButtonSwitch(language)[0]}</button>
          <button  onClick={() => {
              setIntroductionPage(0);
            }}>{renderButtonSwitch(language)[1]}</button>
        </div>
      </div>{" "}
      <Footer />
    </div>
  );
};
export default MainPage;

There is a language selector on the component Header.jsx, I would like to change the language, then change the content of MainPage. However, it doesn’t work.

import React from "react";
import { useMainPageContext } from "../Hooks/mainPageContext";

const Header = () => {
  const context = useMainPageContext();
const {
  language,
  onSetLanguage,
} = context;

  return (
    <div className="header">
      <h1
        style={{
            display: "flex",
            flexFlow:"row",
            alignItems:"center",
          width: "calc(100% - 10%)",
          height: "4vh",
         
        }}
      >
        <div style={{display:"flex", color: "#F5821F",}}>
         <img src={require("../Images/Logo.png")} style={{width:"50%", height:"7.5%", marginTop:"0vh"}} alt="image name"/>
        <div style={{ top: "0", margin: "0vh", marginLeft:"2vw", width:" 100%", fontSize:"3vw"}}>中心</div>    
        </div>

        <div><div style={{marginTop:"1vh", fontSize:"2vw"}} onClick={()=>{language===1? onSetLanguage(0):onSetLanguage(1);
        }}>繁體/ English</div></div>
      </h1>
     
    </div>
  );
};
export default Header;

2

Answers


  1. Chosen as BEST ANSWER

    I have changed the coding , so that it is a context variable passed to the mainPage.js, however, I have another problem, the missing transition key.

    Here is my i18n.js

    import i18n from 'i18next';
    import { initReactI18next } from 'react-i18next';
    
    
    
    i18n
      .use(initReactI18next)
      .init({
        backend: {
            loadPath: `/locales/{{lng}}/translation.json`,
            parse: data => data,
          },
        lng: 'en',
        fallbackLng: 'en',
        debug: true,
        resources: {
          'en': {
            translation: 'en',
          },
          'tw': {
            translation: 'tw',
          },
        },
       
        interpolation: {
          escapeValue: false
        }
      });
    
    export default i18n;
    

    Here is the App.js

    import React , { Component, Suspense , useState, useCallback} from 'react';
    import { useTranslation, withTranslation, Trans ,I18nextProvider} from 'react-i18next';
    
    
    import ReactDOM from "react-dom/client";
    import{
      createBrowserRouter, RouterProvider,BrowserRouter as Router
    } from "react-router-dom";
    import logo from './logo.svg';
    import './App.css';
    
    //Import the pages
    import MainPage from "./MainPage/MainPage";
    import A1SubjectPage1 from "./ASubject/A1SubjectPage1";
    import B1ResearcherPage1 from "./BResearcher/B1ResearcherPage1";
    import Header from './Resources/Components/Header';
    
    // use hoc for class based components
    
    
    
    class LegacyWelcomeClass extends Component {
      render() {
        const { t } = this.props;
        return <h2>{t('title')}</h2>;
      }
    }
    const Welcome = withTranslation()(LegacyWelcomeClass);
    
    // Component using the Trans component
    /*function MyComponent() {
      return (
        <Trans i18nKey="description.part1">
          To get started, edit <code>src/App.js</code> and save to reload.
        </Trans>
      );
    }
    */
    // page uses the hook
    
    
    
    function App() {
    
    
      const { t, i18n } = useTranslation();
    
      const [language, setLanguage] = useState('en');
    
      const onSetLanguage = useCallback((lng) => {
        setLanguage(lng);
      }, []);
    
      const router = createBrowserRouter([
        {
          path: "/",
          element: <div><MainPage/></div>,
        },
        {
          path: "/mainPage",
          element: <div>wowkdjfkdow<MainPage /></div>,
        },
        {
          path: "/A1SubjectPage1",
          element: <div>puripuri<A1SubjectPage1 /></div>,
        },
        {
          path: "/B1ResearcherPage1",
          element: <div>ReRe<B1ResearcherPage1 /></div>,
        },
      ]);
     
      ReactDOM.createRoot(document.getElementById("root")).render(
        <I18nextProvider i18n={i18n}>
        <React.StrictMode>
          <RouterProvider router={router} />
        </React.StrictMode>
        </I18nextProvider>
      );
    
    
    let routes;
    
    
    
    
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> This is a project
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Hello World Again and Again
            </a>
          </header>
          <Router>
          <div className="App-intro">
           
          </div>
        
            <main>{routes}</main>
          </Router>
        </div>
      );
    }
    
    export default App;
    

    Here is the mainPage.js

    import React, { useState, useEffect, Component , Suspense, useCallback} from "react";
    import Header from "../Resources/Components/Header";
    import Footer from "../Resources/Components/Footer";
    import { useTranslation, withTranslation, Trans } from 'react-i18next';
    import {MainPageContext, useMainPageContext } from "../Resources/Hooks/mainPageContext";
    
    import "./MainPage.css";
    
    class LegacyWelcomeClass extends Component {
      render() {
        const { t } = this.props;
        return <h2>{t('title')}</h2>;
      }
    }
    const Welcome = withTranslation()(LegacyWelcomeClass);
    
    const MainPage = () => {
      const { t, i18n } = useTranslation();
    const context = useMainPageContext();
    const [language, setLanguage] = useState('tw');
    
      const onSetLanguage = useCallback((lng) => {
        setLanguage(lng);
      }, []);
    
    
    
    
    
      const [introductionPage, setIntroductionPage] = useState(0);
    
      //const [language, setLanguage]= useState(0);
    
      //below is the script of the test description. 隨時可以加入新array做新language。
    
      
      const renderLanguageSwitch = () => {
        return [t('testStart'), t('testAgreement')];
      };
      
      const renderButtonSwitch = () => {
        return [t('agree'), t('disagree')];
      };
    
      return (
        <div className="MainPage">
        <Trans i18nKey="title">
      <h2>{t('title')}</h2>
    </Trans>
    
      
          <Header onSetLanguage={onSetLanguage} />
          <div
            style={{
              width: "100%",
              height: "100vh",
              backgroundColor: "#F5821F",
              margin: "0",
            }}
          >
            {introductionPage === 0 && (
              <button
                className="testStartBox"
                onClick={() => {
                  setIntroductionPage(1);
                }}
              >
              {t('agree')}, {t('disagree')}
              </button>
            )}
            {introductionPage !== 0 && (
              <div>
              <div
                className="testDescriptionBox"
                onClick={() => {
                  setIntroductionPage(introductionPage + 1);
                }}
              >
               {t('description')}
              </div>
              <div className="testAgreement">
    
              </div>
              </div>
            )}
    
            <div
              className="buttonWrapper"
              style={{ display: introductionPage === 1 ? "" : "none" }}
            >
              <button  onClick={() => {
                  setIntroductionPage(introductionPage + 1);
                }}> {t('description')}</button>
              <button  onClick={() => {
                  setIntroductionPage(0);
                }}>{t('agreement')}</button>
            </div>
          </div>{" "}
          <Footer />
    
        
        </div>
      );
    };
    export default MainPage;
    

    Here is the Header.js

    import React, { useCallback, useContext } from "react";
    import { useMainPageContext } from "../Hooks/mainPageContext";
    import { useTranslation } from 'react-i18next';
    
    const Header = () => {
      const { t, i18n } = useTranslation();
      const context = useMainPageContext();
      const { onSetLanguage } = context;
    
      const toggleLanguage = useCallback((lng) => {
        i18n.changeLanguage(lng);
        onSetLanguage(lng);
      }, [i18n, onSetLanguage]);
    
      const currentLanguage = i18n.language;
    
      return (
        <div className="header">
          <h1
            style={{
                display: "flex",
                flexFlow:"row",
                alignItems:"center",
              width: "calc(100% - 10%)",
              height: "4vh",
              backgroundColor: "white",
              paddingTop:"0",
              padding: "2.5%",
              paddingLeft: "5%",
              paddingRight: "5%",
              justifyContent:"space-between"
            }}
          >
            <div style={{display:"flex", color: "#F5821F",}}>
             <img src={require("../Images/cmghLogo.png")} style={{width:"50%", height:"7.5%", marginTop:"0vh"}} alt="logo"/>
            <div style={{ top: "0", margin: "0vh", marginLeft:"2vw", width:" 100%", fontSize:"3vw"}}>中心</div>    
            </div>
            <div>
              <header>
                <button onClick={() => toggleLanguage('en')} disabled={currentLanguage === 'en'}>English</button>
                <button onClick={() => toggleLanguage('tw')} disabled={currentLanguage === 'tw'}>中文</button>
              </header>
            </div>
          </h1>
        </div>
      );
    };
    
    export default Header;
    

  2. The i18n.js did not set properly.
    so that failed to read the translation key-value pair.

    After I changed to install and using "i18next-http-backend" plugin, modified the i18n.js, the problem is fixed as the following:

    import i18n from 'i18next';
    import Backend from 'i18next-http-backend';
    import LanguageDetector from 'i18next-browser-languagedetector';
    import { initReactI18next } from 'react-i18next';
    
    i18n
      // load translation using http -> see /public/locales
      // learn more: https://github.com/i18next/i18next-http-backend
      .use(Backend)
      // detect user language
      // learn more: https://github.com/i18next/i18next-browser-languageDetector
      .use(LanguageDetector)
      // pass the i18n instance to react-i18next.
      .use(initReactI18next)
      // init i18next
      // for all options read: https://www.i18next.com/overview/configuration-options
      .init({
        fallbackLng: 'en',
        debug: true,
    
        interpolation: {
          escapeValue: false, // not needed for react as it escapes by default
        },
      });
    
    export default i18n;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search