当前位置:首页 > 文章列表 > 文章 > 前端 > 使用 i 翻译你的 React 项目从未如此简单

使用 i 翻译你的 React 项目从未如此简单

来源:dev.to 2024-08-24 14:18:51 0浏览 收藏

IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《使用 i 翻译你的 React 项目从未如此简单》,聊聊,我们一起来看看吧!

使用 i 翻译你的 React 项目从未如此简单

说疯狂的开发者!

今天我将向您展示,将整个项目翻译成 react 从未像现在这样容易。但首先您需要知道为什么这很重要。

当人们开始编程时,代码文本和消息通常使用葡萄牙语(pt-br)。将项目翻译成其他语言从来都不是优先事项,并且被认为是复杂或不必要的。

那么为什么它会相关呢?

这取决于你的实际情况。以下是您应该考虑此过程的一些原因:

公司需要
可能是您工作的公司或您拥有的某些 saas 开始在另一个国家/地区运营并且有此需求。具有此功能的产品有巨大的差异。

申请国​​际职位空缺
如果您正在申请国际职位空缺,拥有包含国际化项目的作品集可以给您带来引人注目的亮点。这表明您已准备好从事全球项目,并且不像大多数人一样懒惰。

你永远不会学太多
国际化不仅是一种特征,也是一种重要的学习经历。这是您的技能和工具库中的另一种武器。

过去是如何做到的?

项目翻译已经是个老问题了。人们在 html 中选择了该国家的国旗,供人们选择,并在代码中用 if 填充以了解将显示哪些文本。
这是非常被忽视的。网站是用单一语言制作的,翻译是随意添加的。如果是在后端,交易会更糟糕。

随着互联网的全球化,对多语言软件的需求不断增长,带来了针对国际化的特定工具。像 gnu gettext 这样的解决方案出现在后端,随后出现了像 i18next 和 react-intl 这样的前端库。然后疑问就来了...

i18next 对比react-intl:选择哪一个?

  • i18next:这个出现于 2011 年,它是一个 npm 包,适用于客户端的 node.js 和 spa。社区采纳了它,并最终于2015年在react-i18next lib中制作了react版本。因此,作为积极和消极的点,我们有:

    • 优点:灵活性、路上时间(自 2011 年起)、庞大的生态系统(一次学习,随处翻译)和自动回退。
    • 缺点:学习曲线。有很多文档需要阅读,但并不是您需要的所有内容都在那里。
  • react-intl:formatjs 项目的一部分,遵循国际 javascript api 标准,确保与现代浏览器的兼容性。

    • 优点:与 ecmascript 标准保持一致,集成简单。
    • 缺点:灵活性较差,插件支持较少。

我们将使用哪一个?

i18下一个我的朋友们!我总是建议阅读文档来开始,但让我们看看 doido 的指南!

使用 i18next 国际化 react 应用程序

  1. 安装
   npm install i18next i18next-chained-backend i18next-http-backend i18next-resources-to-backend react-i18next next-i18next 

  1. 配置:创建一个i18n.js来配置i18next。
   import i18n from 'i18next';
   import { initreacti18next } from 'react-i18next';
   import backend from 'i18next-http-backend';
   import languagedetector from 'i18next-browser-languagedetector';

   i18n
     .use(backend)
     .use(languagedetector)
     .use(initreacti18next)
     .init({ fallbacklng: 'en', interpolation: { escapevalue: false } });

   export default i18n;
  1. translations:在 locales/en/translation.json 和 locales/pt/translation.json 中创建翻译文件。
   {
     "welcome": "welcome to our application!",
     "login": "login"
   }
  1. 翻译的使用:在 react 中使用 usetranslation 钩子。
   import react from 'react';
   import { usetranslation } from 'react-i18next';

   function app() {
     const { t } = usetranslation();

     return (
       <div>
         <h1>{t('welcome')}</h1>
         <button>{t('login')}</button>
       </div>
     );
   }

   export default app;
  1. 语言更改:允许用户更改语言。
   import react from 'react';
   import { usetranslation } from 'react-i18next';

   function languageswitcher() {
     const { i18n } = usetranslation();

     const changelanguage = (lng) => i18n.changelanguage(lng);

     return (
       <div>
         <button onclick={() => changelanguage('en')}>english</button>
         <button onclick={() => changelanguage('pt')}>português</button>
       </div>
     );
   }

   export default languageswitcher;

这就是全部吗?

当然不是,我现在向您展示我在 crazystack 项目中做了什么。首先,我在 nextjs 中做了一个不同的配置,采用了我在项目本身的公共文件夹中定义的静态 json!看看:

import i18next from "i18next";
import chainedbackend from "i18next-chained-backend";
import httpbackend from "i18next-http-backend";
import resourcestobackend from "i18next-resources-to-backend";
import { initreacti18next } from "react-i18next";
import { defaulttexts } from "./defaulttexts";

i18next
  .use(chainedbackend)
  .use(initreacti18next)
  .init({
    lng: "pt-br",
    fallbacklng: "pt-br",
    interpolation: {
      escapevalue: false,
    },
    compatibilityjson: "v3",
    react: {
      //wait: true,//usar no react native
      usesuspense: false,
    },
    backend: {
      backends: [httpbackend, resourcestobackend(defaulttexts)],
      backendoptions: [
        {
          loadpath: `${process.env.next_public_url}/{{lng}}/{{ns}}.json`,
        },
      ],
    },
  });

然后我创建了一个上下文 api 来保存语言并在整个项目中访问它。从进口开始

2. 进口

import { usetranslation } from "react-i18next";
import { createcontext, usestate, usecontext } from "react";
  • usetranslation:react-i18next 挂钩来访问翻译功能。在这里,您将在项目中几乎每个 jsx 组件中使用它。
  • createcontext、usestate、usecontext:用于创建和使用上下文以及管理状态的 react 函数。

3. 上下文创建

const i18ncontext = createcontext({} as any);

创建上下文来通过 dom 存储和提供数据(例如当前语言)。

4. 环境检查

export const isbrowser = typeof window !== "undefined";

此行检查代码是否在浏览器中运行(而不是在服务器上),这对于处理 localstorage 等特定于客户端的功能至关重要。

5.i18nprovider组件

export const i18nprovider = ({ children }: any) => {
  const { i18n } = usetranslation() || {};
  const [currentlanguage, setcurrentlanguage] = usestate(
    formatlanguagefromi18n(i18n?.language)
  );
  const changelanguage = (language) => {
    setcurrentlanguage(language);
    i18n?.changelanguage?.(formatlanguagefromselect(language));
    localstorage.setitem("language", formatlanguagefromselect(language));
  };
  return (
    <i18ncontext.provider value={{ changelanguage, currentlanguage, setcurrentlanguage }}>
      {children}
    </i18ncontext.provider>
  );
};

这个组件是一个provider,它包装了react组件树并提供了语言的当前状态以及更改它的函数。

  • usetranslation:从react-i18next库中检索i18n对象,其中包含有关当前语言的信息。
  • currentlanguage:存储当前语言的state,根据i18n检测到的语言进行初始化。
  • changelanguage:更改语言的函数,这也会将选择保存在 localstorage 中,以便在页面重新加载之间保持持久性。

6. 挂钩使用i18n

export const usei18n = () => {
  if (!isbrowser) {
    return {
      currentlanguage: "pt-br",
      setcurrentlanguage: () => {},
      changelanguage: () => {},
    };
  }
  return usecontext(i18ncontext);
};

这个钩子可以轻松访问任何组件中的国际化上下文。

  • 检查您是否在浏览器中(isbrowser)。如果没有,则返回默认值,以避免服务器端出错。
  • 如果在浏览器中,则消耗并返回 i18ncontext 上下文。

7. 转换图

const countrytolanguage = {
  br: "pt-br",
  us: "en",
};
const languagetocountry = {
  "pt-br": "br",
  en: "us",
};

这些对象将国家/地区代码映射到语言代码,反之亦然,从而可以轻松地在不同约定之间格式化语言代码。

8. 格式化函数

export const formatlanguagefromi18n = (language) => languagetocountry[language];
export const formatlanguagefromselect = (language) => countrytolanguage[language];

这些函数根据需要格式化语言环境。 formatlanguagefromi18n 将语言代码转换为国家/地区代码,而 formatlanguagefromselect 则进行反向转换。

完整代码

"use client";
import { usetranslation } from "react-i18next";
import { createcontext, usestate, usecontext } from "react";

const i18ncontext = createcontext({} as any);

export const isbrowser = typeof window !== "undefined";

export const i18nprovider = ({ children }: any) => {
  const { i18n } = usetranslation() || {};
  const [currentlanguage, setcurrentlanguage] = usestate(
    formatlanguagefromi18n(i18n?.language)
  );
  const changelanguage = (language) => {
    setcurrentlanguage(language);
    i18n?.changelanguage?.(formatlanguagefromselect(language));
    localstorage.setitem("language", formatlanguagefromselect(language));
  };
  return (
    <i18ncontext.provider value={{ changelanguage, currentlanguage, setcurrentlanguage }}>
      {children}
    </i18ncontext.provider>
  );
};

export const usei18n = () => {
  if (!isbrowser) {
    return {
      currentlanguage: "pt-br",
      setcurrentlanguage: () => {},
      changelanguage: () => {},
    };
  }
  return usecontext(i18ncontext);
};

const countrytolanguage = {
  br: "pt-br",
  us: "en",
};

const languagetocountry = {
  "pt-br": "br",
  en: "us",
};

export const formatlanguagefromi18n = (language) => languagetocountry[language];
export const formatlanguagefromselect = (language) => countrytolanguage[language];

然后我改变了导航栏

在代码中,我使用国家/地区下拉菜单选择语言。看看:

"use client";
//@ts-nocheck
import { header, flex, logo, profile, notificationsnav, searchbar } from "@/shared/ui";
import { usebreakpointvalue, icon, iconbutton, usemediaquery } from "@chakra-ui/react";
import { rimenuline } from "react-icons/ri";
import { useauth, usesidebardrawer } from "@/shared/libs";
import { useeffect, usestate } from "react";
import { countrydropdown } from "react-country-region-selector";
import { theme } from "@/application/theme";
import { formatlanguagefromi18n, usei18n } from "@/application/providers/i18nprovider";
import { usetranslation } from "react-i18next";

export const navbar = ({ showlogo = true }) => {
  const { isauthenticated } = useauth() || {};
  const { i18n } = usetranslation();
  const { changelanguage, setcurrentlanguage } = usei18n() || {};
  const { onopen = () => {}, onclose } = usesidebardrawer() || {};
  const isdesktopversion = usebreakpointvalue({ base: false, lg: true });
  const [country, setcountry] = usestate(formatlanguagefromi18n(i18n?.language));
  useeffect(() => {
    return () => {
      onclose?.();
    };
  }, []);
  const dropdown = countrydropdown as any;
  useeffect(() => {
    const language = localstorage.getitem("language");
    if (language) {
      setcountry(formatlanguagefromi18n(language));
      setcurrentlanguage(language);
      i18n?.changelanguage?.(language);
    }
  }, []);
  return (
    <header>
      <flex alignitems={"center"} w={"100%"}>
        {isauthenticated && !isdesktopversion && (
          <iconbutton
            aria-label="open sidebar"
            fontsize="24"
            icon={<icon as={rimenuline} />}
            variant="unstyled"
            onclick={onopen}
            mr="1"
            mt={2}
          />
        )}
        <logo marginbottom={0} />
        {/* {islargerthan560 && (
          <searchbar placeholder="pesquise por nome..." name="search" width="auto" />
        )} */}
        {isauthenticated && (
          <flex align="center" ml="auto">
            {/* <notificationsnav /> */}
            <dropdown
              value={country}
              onchange={(val) => {
                setcountry(val);
                changelanguage(val);
              }}
              labeltype="short"
              valuetype="short"
              showdefaultoption
              defaultoptionlabel="selecione o idioma"
              whitelist={["us", "br"]}
              style={{
                backgroundcolor: theme.colors.secondary[400],
                padding: 10,
                width: 60,
                marginright: 15,
                borderradius: 8,
              }}
            />
            <profile showprofiledata={isdesktopversion} />
          </flex>
        )}
      </flex>
    </header>
  );
};

导入和初始设置:

  • useauth:检查用户是否经过身份验证。
  • usebreakpointvalue:根据屏幕大小决定是否显示桌面版本。
  • usestate:设置国家/语言(国家)的初始状态,使用formatlanguagefromi18n函数格式化i18n的当前语言
  • useeffect:第一个效果是在卸载组件时清除侧边栏(onclose)。第二个效果检查语言是否保存在 localstorage 中,如果是,则更新国家/地区状态并更改应用程序中的语言。

语言下拉菜单:

  • 下拉列表是使用react-country-region-selector库的countrydropdown组件实现的,该组件被定制为用作语言选择器。
  • value={country}:下拉列表中选择的值由国家/地区控制。
  • onchange={(val) => { ... }}:当下拉值改变时,更新国家状态,并调用changelanguage函数更改应用程序语言。
  • whitelist={["us", "br"]}:将下拉选项限制为“us”(英语)和“br”(葡萄牙语)。
  • style={...}:下拉菜单的自定义内联样式,使用主题的颜色和间距。
  1. 语言选择器行为
    • 下拉列表允许用户选择首选语言,并且此选择会保留在 localstorage 中。
    • 更改语言时,下拉列表会反映此更改,并且应用程序会更新为使用新选择的语言。 要在文章中包含您在图像中提供的代码片段,您可以遵循以下格式:

以及如何更改文本?

从一个组件到另一个组件,我都遵循相同的过程。下面的代码展示了如何根据本地化密钥用动态翻译替换静态文本:

import { Divider } from "@chakra-ui/react";
import { IoExitOutline } from "react-icons/io5";
import { useRouter } from "next/navigation";
import { useTranslation } from "react-i18next";  // Importando o hook useTranslation

type ProfileProps = {
  showProfileData?: boolean;
};

export const Profile = ({ showProfileData }: ProfileProps) => {
  const { t } = useTranslation(["PAGES"]);  // Obtendo a função t para tradução
  const { user, logout } = useAuth() || {};
  const router = useRouter();
  const { showUserMenu, setShowUserMenu } = useProfile();

  return (
    <Box>
      {/* Outras partes do componente */}
      <Flex>
        <IoExitOutline />
        <Text fontSize="sm">
          {t("PAGES:HOME_PAGE.logout", { defaultValue: "Sair" })}  // Chave de tradução com valor padrão
        </Text>
      </Flex>
    </Box>
  );
};

在此示例中,usetranslation 挂钩用于加载 pages:home_page.logout 翻译键。如果未找到该密钥,将显示默认文本“退出”。

结论

这个想法可以应用于任何静态文本组件。只需使用 usetranslation 钩子即可。
国际化您的应用程序可以打开全球市场的大门,突出您的投资组合并提高您的技能。在 i18next 和 react-intl 之间进行选择取决于您项目的具体需求,但对于那些想要入门的人来说,两者都是很好的选择。

课程建议

2022 年,我创建了crazystack 训练营。在其中,我展示了在线服务调度系统的 2 个完整应用程序,应用了设计模式、简洁架构、功能切片设计、solid、ddd 以及单元、集成和 e2e 测试等先进概念。

在第一个应用程序中,您将学习如何在 node.js 生态系统中构建 rest api。将创建涉及复杂业务规则的用例,例如列出可用时间、根据预订生成订单、忠诚度系统、佣金、付款、客户评论等等。一切都在 typescript 中完成并使用非关系数据库 mongodb。

在第二个应用程序中,您将学习如何在 react.js 生态系统中构建管理面板来查看图表和操作记录。一切都是通过 typescript 和 next.js 框架完成的。此外,还将使用chakra ui可视化组件库,将原子设计概念应用于创建的组件。要了解更多信息,请访问crazystack.com.br。

本篇关于《使用 i 翻译你的 React 项目从未如此简单》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

版本声明
本文转载于:dev.to 如有侵犯,请联系study_golang@163.com删除
SOLID 原则使用一些有趣的类比与车辆示例SOLID 原则使用一些有趣的类比与车辆示例
上一篇
SOLID 原则使用一些有趣的类比与车辆示例
使用 React Router v6 进行布局
下一篇
使用 React Router v6 进行布局
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 茅茅虫AIGC检测:精准识别AI生成内容,保障学术诚信
    茅茅虫AIGC检测
    茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
    153次使用
  • 赛林匹克平台:科技赛事聚合,赋能AI、算力、量子计算创新
    赛林匹克平台(Challympics)
    探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
    182次使用
  • SEO  笔格AIPPT:AI智能PPT制作,免费生成,高效演示
    笔格AIPPT
    SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
    170次使用
  • 稿定PPT:在线AI演示设计,高效PPT制作工具
    稿定PPT
    告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
    157次使用
  • Suno苏诺中文版:AI音乐创作平台,人人都是音乐家
    Suno苏诺中文版
    探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
    189次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码