Rumah > Artikel > hujung hadapan web > TERJEMAHAN projek React anda dengan i tidak pernah semudah ini
Hari ini saya akan menunjukkan kepada anda bahawa menterjemah KESELURUHAN projek ke dalam React tidak pernah semudah sekarang. Tetapi pertama-tama anda perlu tahu mengapa ini penting.
Apabila orang memulakan pengaturcaraan, adalah perkara biasa untuk teks dan mesej kod dalam bahasa Portugis (pt-BR). Menerjemahkan projek ke dalam bahasa lain tidak pernah menjadi keutamaan dan dianggap rumit atau tidak perlu.
Ia bergantung pada realiti anda. Berikut ialah beberapa sebab mengapa anda perlu mempertimbangkan proses ini:
Syarikat memerlukannya
Mungkin syarikat tempat anda bekerja atau beberapa SaaS yang anda miliki mula beroperasi di negara lain dan mempunyai keperluan ini. Produk yang mempunyai fungsi ini mempunyai perbezaan yang BESAR.
Permohonan jawatan kosong antarabangsa
Jika anda memohon jawatan kosong antarabangsa, mempunyai portfolio dengan projek yang telah diantarabangsakan boleh memberi anda sorotan yang menarik. Ini menunjukkan bahawa anda bersedia untuk mengerjakan projek global dan tidak malas seperti kebanyakan orang.
Anda tidak boleh belajar terlalu banyak
Pengantarabangsaan bukan sekadar ciri, tetapi juga pengalaman pembelajaran yang penting. Ia adalah senjata lain yang anda sertakan dalam senjata kemahiran dan alatan anda.
Penterjemahan projek sudah menjadi masalah lama. Orang membuat pilihan itu dalam HTML dengan bendera negara untuk orang ramai memilih dan mengisinya dengan jika dalam kod untuk mengetahui teks yang akan dipaparkan.
Ia amat diabaikan. Tapak web dibuat dalam satu bahasa, dan terjemahan ditambah secara sembarangan. Jika ia berada di bahagian belakang, perjanjian itu akan menjadi lebih teruk.
Dengan globalisasi internet, permintaan untuk perisian berbilang bahasa telah berkembang, membawa alat khusus untuk i18n. Penyelesaian seperti GNU Gettext muncul di bahagian belakang, diikuti oleh lib seperti i18next dan react-intl untuk bahagian hadapan. Di sinilah timbul keraguan...
i18next: Yang ini muncul pada tahun 2011, ia adalah pakej npm yang berfungsi untuk kedua-dua Node.js dan SPA di bahagian pelanggan. Komuniti menerima pakainya dan akhirnya membuat versi React dalam lib react-i18next pada tahun 2015. Oleh itu, sebagai mata positif dan negatif kita ada:
react-intl: Sebahagian daripada projek FormatJS, mengikut piawaian API JavaScript Antarabangsa, memastikan keserasian dengan penyemak imbas moden.
i18next kawan-kawan saya! Saya sentiasa mengesyorkan membaca dokumen untuk bermula, tetapi mari pergi ke panduan Doido!
npm install i18next i18next-chained-backend i18next-http-backend i18next-resources-to-backend react-i18next next-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;
{ "welcome": "Welcome to our application!", "login": "Login" }
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) => i18n.changeLanguage(lng); return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('pt')}>Português</button> </div> ); } export default LanguageSwitcher;
Sudah tentu tidak, saya kini akan menunjukkan kepada anda perkara yang saya lakukan dalam projek CrazyStack. Mula-mula saya membuat konfigurasi berbeza dalam Nextjs mengambil JSON statik yang saya takrifkan dalam folder awam projek itu sendiri! Lihatlah:
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`, }, ], }, });
Kemudian saya mencipta API konteks untuk menyimpan bahasa dan mengaksesnya sepanjang projek. Bermula dengan import
import { useTranslation } from "react-i18next"; import { createContext, useState, useContext } from "react";
const I18NContext = createContext({} as any);
Konteks dicipta untuk menyimpan dan menyediakan data (seperti bahasa semasa) melalui DOM.
export const isBrowser = typeof window !== "undefined";
Essa linha verifica se o código está sendo executado no navegador (em vez de no servidor), essencial para manipular recursos específicos do cliente, como localStorage.
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> ); };
Este componente é um provider que envolve a árvore de componentes React e fornece o estado atual do idioma e a função para alterá-lo.
export const useI18n = () => { if (!isBrowser) { return { currentLanguage: "pt-br", setCurrentLanguage: () => {}, changeLanguage: () => {}, }; } return useContext(I18NContext); };
Este hook facilita o acesso ao contexto de internacionalização em qualquer componente.
const countryToLanguage = { BR: "pt-br", US: "en", }; const languageToCountry = { "pt-br": "BR", en: "US", };
Esses objetos mapeiam códigos de países para códigos de idiomas e vice-versa, facilitando a formatação dos códigos de idioma entre diferentes convenções.
export const formatLanguageFromi18N = (language) => languageToCountry[language]; export const formatLanguageFromSelect = (language) => countryToLanguage[language];
Essas funções formatam os códigos de idioma conforme necessário. formatLanguageFromi18N converte o código de idioma para o código do país, enquanto formatLanguageFromSelect faz a conversão inversa.
"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];
No código eu tenho um select de idioma utilizando um dropdown de países. Olha só:
"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> ); };
Importações e Setup Inicial:
Dropdown de Idiomas:
De componente em componente eu fui fazendo o mesmo procedimento. O código abaixo mostra como substituir o texto estático por uma tradução dinâmica baseada na chave de localização:
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> ); };
Neste exemplo, o hook useTranslation é utilizado para carregar a chave de tradução PAGES:HOME_PAGE.logout. Se a chave não for encontrada, o texto padrão "Sair" será exibido.
A ideia pode ser aplicada em qualquer componente de texto estático. Basta usar a hook useTranslation.
Internacionalizar sua aplicação pode abrir portas para mercados globais, destacar seu portfólio e aprimorar suas habilidades. Escolher entre i18next e react-intl depende das necessidades específicas do seu projeto, mas ambos são excelentes opções para quem deseja começar.
Em 2022 eu criei o bootcamp CrazyStack. Nele, eu mostro 2 aplicações completas de um sistema de agendamentos online de serviços aplicando conceitos avançados como Design Patterns, Clean Architecture, Feature Sliced Design, SOLID, DDD, além de Testes unitários, de integração e E2E.
Dalam aplikasi pertama, anda akan belajar cara membina API REST dalam ekosistem Node.js. Kes penggunaan akan dibuat melibatkan peraturan perniagaan yang kompleks seperti penyenaraian masa yang tersedia, menjana pesanan daripada janji temu yang ditempah, sistem kesetiaan, komisen, pembayaran, ulasan pelanggan dan banyak lagi. Semuanya dilakukan dalam TypeScript dan menggunakan pangkalan data bukan hubungan MongoDB.
Dalam aplikasi kedua, anda akan belajar cara membina panel pentadbiran dalam ekosistem React.js untuk melihat graf dan memanipulasi rekod. Semua dilakukan dengan TypeScript dan menggunakan rangka kerja Next.js. Tambahan pula, perpustakaan komponen visual UI Chakra akan digunakan, menggunakan konsep Reka Bentuk Atom pada komponen yang dicipta. Untuk mengetahui lebih lanjut, lawati crazystack.com.br.
Atas ialah kandungan terperinci TERJEMAHAN projek React anda dengan i tidak pernah semudah ini. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!