【问题标题】:how to re-render all related components with i18n strings once language is changed更改语言后如何使用 i18n 字符串重新渲染所有相关组件
【发布时间】:2020-12-20 02:50:58
【问题描述】:

这个主 App 函数有一个自定义钩子,当点击按钮时会触发:

import React, { useEffect } from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom'
import HomeScreen from  './Screens/HomeScreen'
import './App.css';
import { useCurrentLang } from './utils/useCurrentLang'
import {strings as engstrings} from './res/lang/eng/strings'

function App() {

  const currentStrings = useCurrentLang(engstrings); 
  return (
    <BrowserRouter>
       <div className="grid-container">
        <header className="header">
          <div className="brand">
            <Link to="/" >
                
            </Link>
          </div>
          <div className="header-side">
            {currentStrings.currentlang.subtitle}
          </div>
          <div className="header-right">
            <button  {...currentStrings}> 
              {currentStrings.currentlang.traduction} 
            </button>
          </div>
          <div>

          </div>
        </header>
        <main className="main">
          <div className="content">
            <Route path="/" exact={true} component={HomeScreen} />
          </div>

        </main>
        <footer className="footer">
          &#169; 2020 
         </footer>
      </div>
    </BrowserRouter>
   
  );
}

export default App;

但是这个从 App 路由的组件函数也需要使用在 App 中找到的钩子对象的相同引用:

import React from 'react';
import terminalImage from '../res/images/GNOMETerminalIcon.png';
import {useCurrentLang} from '../utils/useCurrentLang'
import {strings as engstrings} from '../res/lang/eng/strings'

const { Link } = require("react-router-dom");

function HomeScreen() {
    const currentStrings = useCurrentLang(engstrings); 
    return <div className="home">
        <ul className="menu-list">
            <li>
                <div className="about-link section">
                    <Link to="/about">{currentStrings.currentlang.about}</Link>
                </div>
            </li>
            <li>
                <div className="projects-link section">
                    <Link to="/about">{currentStrings.currentlang.about}</Link>   
                </div>
            </li>
            <li>
                <div className="contacts-link section">
                    <Link to="/about">{currentStrings.currentlang.about}</Link>
                </div>
            </li>
            <li>
                <div className="suggestions-link section">
                    <Link to="/about">{currentStrings.currentlang.about}</Link>   
                </div>
            </li>
        </ul>
        <div className="home-main-image">
            <img src={terminalImage} />
        </div>
    </div>
}

export default HomeScreen;

当 App 上的钩子被触发时,这两个函数是否可以重新渲染?如果是,怎么做?

编辑:currentLang 钩子:

import {useState} from 'react'
import {strings as frstrings} from '../res/lang/fr/strings'
import {strings as engstrings} from '../res/lang/eng/strings'

export const useCurrentLang = initialState => {
    if(initialState === 0){
        initialState = engstrings
    }
    const [currentlang, setLang] = useState(initialState);
    return {
        currentlang: currentlang,
        onClick: () => {
            if(currentlang === engstrings){
                setLang(frstrings)
            } else {
                setLang(engstrings)
            }
        }
    }
}

【问题讨论】:

  • 你能提供useCurrentLang钩子吗?你的Language Context Provider在哪里?
  • @PrãtéékThápá 添加到主帖并进行编辑。

标签: reactjs react-router internationalization react-hooks


【解决方案1】:

问题

您面临的主要问题是React Tree 的一部分不知道语言已更改。

解决方案

使用Language Context 提供所有 React 树的更新并将其包装在应用程序的顶部。用外行的话来说,现在您的应用程序在lang 更改时处于监听模式。所以基本上,React 现在所做的就是每当 lang 发生变化时,它会从上下文中找到使用 lang 的任何位置并更新组件。

关于 React 上下文here的文档

import React from 'react'
// import {strings as frstrings} from '../res/lang/fr/strings'
// import {strings as engstrings} from '../res/lang/eng/strings'

const lang = {
  // in this way, you could dynamically add lang
  // later on which worrying about if-elses in your component
  en: {
    hello: 'hello'
  },
  fr: {
    hello: 'bonjour',
  },
}

const langDict = (key) => lang[key]

const LanguageContext = React.createContext(null);

function LanguageProvider({ initialState = 'en', children }) {
  const [lang, setLang] = React.useState(initialState);

  return (
    <LanguageContext.Provider value={[langDict(lang), setLang]}>
      {children}
    </LanguageContext.Provider>
  )
}

function useLanguage() {
  return React.useContext(LanguageContext);
}

export default function AppWrapper() {
  return (
    <LanguageProvider>
        <App />
    </LanguageProvider>
  )
}

function App() {
  const [lang, setLang] = useLanguage();

  return (
    <div>
      <h1>{lang.hello}</h1>
      <button onClick={() => setLang('fr')}>French</button>
      <button onClick={() => setLang('en')}>English</button>
    </div>
  )
}

【讨论】:

  • 问题,我如何在 App 功能中使用语言提供程序,因为我似乎无法在 之外使用 useLanguage
  • 为什么需要在 LanguageProvider 之外使用 useLanguage
  • 因为我不能在 Html 字段中声明对象?抱歉,已经很晚了,我有点困惑如何在 App 函数中调用我的提供程序。
  • 您必须从LanguageProvider 内部调用useLanguage。如果你想调用应用程序,那么你必须将你的LanguageProvider 移动到你正在使用&lt;App /&gt;index.js 文件,然后你可以做类似&lt;LanguageProvider&gt;&lt;App /&gt;&lt;/LanguageProvider&gt;
  • 检查this。我也更新了代码。
猜你喜欢
  • 1970-01-01
  • 2018-12-06
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 2018-04-20
  • 2021-02-15
  • 1970-01-01
相关资源
最近更新 更多