reactjs 为什么上下文变量无法从componet Header.jsx传递到mainPage.js

sdnqo3pr  于 2023-02-22  发布在  React
关注(0)|答案(2)|浏览(82)

我希望mainPage内布局使用的措辞会根据组件Header.jsx中选择的语言进行更改。但是,Header.jsx中的更改无法传递到Header.jsx,因此,当单击语言选择器时,注解会发生更改。

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;

组件Header.jsx上有一个语言选择器,我想改变语言,然后改变主页的内容。但是,它不起作用。

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;
bfrts1fy

bfrts1fy1#

我已经更改了编码,使其成为传递给mainPage.js的上下文变量,但是,我还有另一个问题,即缺少转换键。
这是我的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;

下面是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;

这里是主页面. 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;

下面是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;
0ejtzxu1

0ejtzxu12#

i18n.js未正确设置,因此无法读取转换键值对。
我改为安装使用“i18 next-http-backend”插件,修改i18n.js后,问题修复如下:

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;

相关问题