Rumah  >  Artikel  >  hujung hadapan web  >  TERJEMAHAN projek React anda dengan i tidak pernah semudah ini

TERJEMAHAN projek React anda dengan i tidak pernah semudah ini

王林
王林asal
2024-08-24 11:04:05506semak imbas

Nunca foi tão fácil TRADUZIR seu projeto React com i

Katakan dev gila!

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.

Jadi mengapa ia relevan?

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.

Bagaimana ia dilakukan pada masa lalu?

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 lwn. react-intl: Mana satu untuk dipilih?

  • 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:

    • Kebaikan: Fleksibiliti, masa jalan raya (sejak 2011), ekosistem yang luas (belajar sekali menterjemah di mana-mana) dan sandaran automatik.
    • Keburukan: Keluk pembelajaran. Terdapat banyak dokumen untuk dibaca, tetapi tidak semua yang anda perlukan ada.
  • react-intl: Sebahagian daripada projek FormatJS, mengikut piawaian API JavaScript Antarabangsa, memastikan keserasian dengan penyemak imbas moden.

    • Kebaikan: Sejajar dengan piawaian ECMAScript, kesederhanaan dalam penyepaduan.
    • Keburukan: Kurang fleksibel dan kurang sokongan pemalam.

Dan yang mana satu yang akan kita gunakan?

i18next kawan-kawan saya! Saya sentiasa mengesyorkan membaca dokumen untuk bermula, tetapi mari pergi ke panduan Doido!

Mengantarabangsakan Aplikasi React dengan i18next

  1. Pemasangan:
   npm install i18next i18next-chained-backend i18next-http-backend i18next-resources-to-backend react-i18next next-i18next 

  1. Konfigurasi: Cipta i18n.js untuk mengkonfigurasi 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. Terjemahan: Buat fail terjemahan dalam locales/en/translation.json dan locales/pt/translation.json.
   {
     "welcome": "Welcome to our application!",
     "login": "Login"
   }
  1. Penggunaan Terjemahan: Gunakan cangkuk useTranslation dalam React.
   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. Perubahan Bahasa: Benarkan pengguna menukar bahasa.
   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;

Adakah itu sahaja?

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

2. Import

import { useTranslation } from "react-i18next";
import { createContext, useState, useContext } from "react";
  • useTranslation: React-i18next hook untuk mengakses ciri terjemahan. Ini di sini anda akan gunakan dalam hampir setiap komponen JSX yang anda ada dalam projek.
  • createContext, useState, useContext: Fungsi bertindak balas untuk mencipta dan menggunakan konteks, serta mengurus keadaan.

3. Penciptaan Konteks

const I18NContext = createContext({} as any);

Konteks dicipta untuk menyimpan dan menyediakan data (seperti bahasa semasa) melalui DOM.

4. Verificação do Ambiente

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.

5. Componente 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>
  );
};

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.

  • useTranslation: Recupera o objeto i18n da biblioteca react-i18next, que contém informações sobre o idioma atual.
  • currentLanguage: Estado que armazena o idioma atual, inicializado com base no idioma detectado pelo i18n.
  • changeLanguage: Função para alterar o idioma, que também salva a escolha no localStorage para persistência entre recargas da página.

6. Hook useI18n

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.

  • Verifica se está no navegador (isBrowser). Se não estiver, retorna valores padrão para evitar erros no server side.
  • Se estiver no navegador, consome e retorna o contexto I18NContext.

7. Mapas de Conversão

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.

8. Funções de Formatação

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.

Código completo

"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];

Depois eu mexi na Navbar

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:

  • useAuth: Verifica se o usuário está autenticado.
  • useBreakpointValue: Determina se a versão desktop deve ser exibida com base no tamanho da tela.
  • useState: Define o estado inicial do país/língua (country) usando a função formatLanguageFromi18N para formatar a língua atual do i18n.
  • useEffect: Primeiro efeito limpa o sidebar ao desmontar o componente (onClose). O segundo efeito verifica se o idioma está salvo no localStorage e, caso esteja, atualiza o estado country e muda o idioma na aplicação.

Dropdown de Idiomas:

  • O dropdown é implementado usando o componente CountryDropdown da biblioteca react-country-region-selector, que é customizado para servir como um seletor de idioma.
  • value={country}: O valor selecionado no dropdown é controlado pelo estado country.
  • onChange={(val) => { ... }}: Quando o valor do dropdown é alterado, o estado country é atualizado, e a função changeLanguage é chamada para alterar o idioma da aplicação.
  • whitelist={["US", "BR"]}: Restringe as opções do dropdown a "US" (inglês) e "BR" (português).
  • style={...}: Estilização inline personalizada para o dropdown, utilizando cores e espaçamentos do tema theme.
  1. Comportamento do Seletor de Idioma:
    • O dropdown permite que o usuário selecione o idioma preferido, e essa seleção é persistida no localStorage.
    • Ao mudar o idioma, o dropdown reflete essa mudança, e a aplicação é atualizada para usar o novo idioma selecionado. Para incluir o trecho de código que você forneceu na imagem no seu artigo, você pode seguir este formato:

E como mudar os textos?

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.

Conclusão

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.

Sugestão de cursos

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn