日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:52010
  • 待審:67
  • 小程序:12
  • 文章:1106242
  • 會員:784

說瘋狂的開發者!

今天我將向您展示,將整個項目翻譯成 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 應用程序

    安裝

   npm install i18next i18next-chained-backend i18next-http-backend i18next-resources-to-backend react-i18next next-i18next 

登錄后復制

    配置:創建一個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;

登錄后復制

    translations:在 locales/en/translation.json 和 locales/pt/translation.json 中創建翻譯文件。

   {
     "welcome": "welcome to our application!",
     "login": "login"
   }

登錄后復制

    翻譯的使用:在 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;

登錄后復制

    語言更改:允許用戶更改語言。

   import react from 'react';
   import { usetranslation } from 'react-i18next';

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

     const changelanguage = (lng) =&gt; i18n.changelanguage(lng);

     return (
       <div>
         <button onclick="{()"> changelanguage('en')}&gt;english</button>
         <button onclick="{()"> changelanguage('pt')}&gt;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) =&gt; {
  const { i18n } = usetranslation() || {};
  const [currentlanguage, setcurrentlanguage] = usestate(
    formatlanguagefromi18n(i18n?.language)
  );
  const changelanguage = (language) =&gt; {
    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 = () =&gt; {
  if (!isbrowser) {
    return {
      currentlanguage: "pt-br",
      setcurrentlanguage: () =&gt; {},
      changelanguage: () =&gt; {},
    };
  }
  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) =&gt; languagetocountry[language];
export const formatlanguagefromselect = (language) =&gt; 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) =&gt; {
  const { i18n } = usetranslation() || {};
  const [currentlanguage, setcurrentlanguage] = usestate(
    formatlanguagefromi18n(i18n?.language)
  );
  const changelanguage = (language) =&gt; {
    setcurrentlanguage(language);
    i18n?.changelanguage?.(formatlanguagefromselect(language));
    localstorage.setitem("language", formatlanguagefromselect(language));
  };
  return (
    <i18ncontext.provider value="{{" changelanguage currentlanguage setcurrentlanguage>
      {children}
    </i18ncontext.provider>
  );
};

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

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

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

export const formatlanguagefromi18n = (language) =&gt; languagetocountry[language];
export const formatlanguagefromselect = (language) =&gt; 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 }) =&gt; {
  const { isauthenticated } = useauth() || {};
  const { i18n } = usetranslation();
  const { changelanguage, setcurrentlanguage } = usei18n() || {};
  const { onopen = () =&gt; {}, onclose } = usesidebardrawer() || {};
  const isdesktopversion = usebreakpointvalue({ base: false, lg: true });
  const [country, setcountry] = usestate(formatlanguagefromi18n(i18n?.language));
  useeffect(() =&gt; {
    return () =&gt; {
      onclose?.();
    };
  }, []);
  const dropdown = countrydropdown as any;
  useeffect(() =&gt; {
    const language = localstorage.getitem("language");
    if (language) {
      setcountry(formatlanguagefromi18n(language));
      setcurrentlanguage(language);
      i18n?.changelanguage?.(language);
    }
  }, []);
  return (
    <header><flex alignitems='{"center"}' w='{"100%"}'>
        {isauthenticated &amp;&amp; !isdesktopversion &amp;&amp; (
          <iconbutton aria-label="open sidebar" fontsize="24" icon="{&lt;icon" as="{rimenuline}"></iconbutton>}
            variant="unstyled"
            onclick={onopen}
            mr="1"
            mt={2}
          /&gt;
        )}
        <logo marginbottom="{0}"></logo>
        {/* {islargerthan560 &amp;&amp; (
          <searchbar placeholder="pesquise por nome..." name="search" width="auto"></searchbar>
        )} */}
        {isauthenticated &amp;&amp; (
          <flex align="center" ml="auto">
            {/* <notificationsnav></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,
              }}
            /&gt;
            <profile showprofiledata="{isdesktopversion}"></profile></dropdown></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={…}:下拉菜單的自定義內聯樣式,使用主題的顏色和間距。

    語言選擇器行為

    下拉列表允許用戶選擇首選語言,并且此選擇會保留在 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) =&gt; {
  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></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。

分享到:
標簽:React 簡單 翻譯 項目
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 52010

    網站

  • 12

    小程序

  • 1106242

    文章

  • 784

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定