Heim > Web-Frontend > js-Tutorial > Das Übersetzen Ihres React-Projekts mit i war noch nie so einfach

Das Übersetzen Ihres React-Projekts mit i war noch nie so einfach

王林
Freigeben: 2024-08-24 11:04:05
Original
618 Leute haben es durchsucht

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

Sag verrückter Entwickler!

Heute zeige ich Ihnen, dass die Übersetzung eines GESAMTEN Projekts in React noch nie so einfach war wie heutzutage. Aber zuerst müssen Sie wissen, warum dies wichtig ist.

Wenn Leute mit dem Programmieren beginnen, sind die Codetexte und Nachrichten häufig auf Portugiesisch (pt-BR). Die Übersetzung des Projekts in andere Sprachen hat nie Priorität und wird als komplex oder unnötig angesehen.

Warum sollte es also relevant sein?

Es hängt von Ihrer Realität ab. Hier sind einige Gründe, warum Sie diesen Prozess in Betracht ziehen sollten:

Das Unternehmen braucht es
Es könnte sein, dass das Unternehmen, in dem Sie arbeiten, oder ein SaaS-Dienst, den Sie haben, in einem anderen Land tätig wird und diesen Bedarf hat. Ein Produkt mit dieser Funktionalität macht einen RIESIGEN Unterschied.

Bewerbung auf eine internationale Stelle
Wenn Sie sich auf internationale Stellen bewerben, kann ein Portfolio mit bereits internationalisierten Projekten ein markantes Highlight sein. Es zeigt, dass Sie bereit sind, an einem globalen Projekt zu arbeiten, und nicht faul sind wie die meisten.

Man kann nie zu viel lernen
Internationalisierung ist nicht nur ein Feature, sondern auch eine wichtige Lernerfahrung. Es ist eine weitere Waffe, die Sie in Ihr Arsenal an Fähigkeiten und Werkzeugen aufnehmen.

Wie wurde das früher gemacht?

Projektübersetzungen sind bereits ein altes Problem. Die Leute haben diese Auswahl im HTML mit der Landesflagge getroffen, damit die Leute sie auswählen können, und sie mit if im Code gefüllt, um zu wissen, welcher Text angezeigt wird.
Es wurde sehr vernachlässigt. Websites wurden in einer einzigen Sprache erstellt und Übersetzungen wurden willkürlich hinzugefügt. Wenn es im Backend wäre, wäre der Deal noch schlimmer.

Mit der Globalisierung des Internets ist die Nachfrage nach mehrsprachiger Software gestiegen und bringt spezielle Tools für i18n mit sich. Im Backend entstanden Lösungen wie GNU Gettext, gefolgt von Bibliotheken wie i18next und React-Intl für das Frontend. Hier kommt der Zweifel ins Spiel...

i18next vs. React-intl: Welches soll ich wählen?

  • i18next: Dieses erschien im Jahr 2011, es war ein npm-Paket, das sowohl für Node.js als auch für SPA auf der Clientseite funktionierte. Die Community hat es übernommen und 2015 schließlich die React-Version in der React-i18next-Bibliothek erstellt. Daher haben wir als positive und negative Punkte:

    • Vorteile: Flexibilität, Reisezeit (seit 2011), riesiges Ökosystem (einmal lernen, überall übersetzen) und automatischer Fallback.
    • Nachteile: Lernkurve. Es gibt viele Dokumente zu lesen, aber nicht alles, was Sie brauchen, ist da.
  • react-intl: Teil des FormatJS-Projekts, folgt internationalen JavaScript-API-Standards und gewährleistet so die Kompatibilität mit modernen Browsern.

    • Vorteile: Ausgerichtet auf ECMAScript-Standards, einfache Integration.
    • Nachteile: Weniger flexibel und weniger Plugin-Unterstützung.

Und welches werden wir verwenden?

i18next meine Freunde! Ich empfehle immer, die Dokumente zu lesen, um loszulegen, aber schauen wir uns Doidos Leitfaden an!

Internationalisierung einer React-Anwendung mit i18next

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

Nach dem Login kopieren
  1. Konfiguration: Erstellen Sie eine i18n.js, um i18next zu konfigurieren.
   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;
Nach dem Login kopieren
  1. Übersetzungen: Erstellen Sie Übersetzungsdateien in locales/en/translation.json und locales/pt/translation.json.
   {
     "welcome": "Welcome to our application!",
     "login": "Login"
   }
Nach dem Login kopieren
  1. Verwendung von Übersetzungen: Verwenden Sie den useTranslation-Hook in 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;
Nach dem Login kopieren
  1. Sprachänderung: Benutzern erlauben, die Sprache zu ändern.
   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;
Nach dem Login kopieren

Ist das alles?

Natürlich nicht, ich zeige euch jetzt, was ich im CrazyStack-Projekt gemacht habe. Zuerst habe ich in Nextjs eine andere Konfiguration erstellt und dabei ein statisches JSON verwendet, das ich im öffentlichen Ordner des Projekts selbst definiert habe! Schauen Sie mal rein:

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`,
        },
      ],
    },
  });
Nach dem Login kopieren

Dann habe ich eine Kontext-API erstellt, um die Sprache zu speichern und im gesamten Projekt darauf zuzugreifen. Beginnend mit Importen

2. Importe

import { useTranslation } from "react-i18next";
import { createContext, useState, useContext } from "react";
Nach dem Login kopieren
  • useTranslation: React-i18next-Hook, um auf Übersetzungsfunktionen zuzugreifen. Dies hier werden Sie in praktisch jeder JSX-Komponente verwenden, die Sie im Projekt haben.
  • createContext, useState, useContext: React-Funktionen zum Erstellen und Konsumieren von Kontexten sowie zum Verwalten des Status.

3. Kontexterstellung

const I18NContext = createContext({} as any);
Nach dem Login kopieren

Es wird ein Kontext erstellt, um Daten (z. B. die aktuelle Sprache) über das DOM zu speichern und bereitzustellen.

4. Verificação do Ambiente

export const isBrowser = typeof window !== "undefined";
Nach dem Login kopieren

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>
  );
};
Nach dem Login kopieren

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);
};
Nach dem Login kopieren

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",
};
Nach dem Login kopieren

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];
Nach dem Login kopieren

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];
Nach dem Login kopieren

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>
  );
};
Nach dem Login kopieren

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>
  );
};
Nach dem Login kopieren

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.

In der ersten Anwendung erfahren Sie, wie Sie eine REST-API im Node.js-Ökosystem erstellen. Es werden Anwendungsfälle mit komplexen Geschäftsregeln wie der Auflistung verfügbarer Zeiten, der Generierung von Bestellungen aus gebuchten Terminen, Treuesystemen, Provisionen, Zahlungen, Kundenbewertungen und vielem mehr erstellt. Alles erfolgt in TypeScript und unter Verwendung der nicht relationalen Datenbank MongoDB.

In der zweiten Anwendung erfahren Sie, wie Sie im React.js-Ökosystem ein Administrationspanel erstellen, um Diagramme anzuzeigen und Datensätze zu bearbeiten. Alles erfolgt mit TypeScript und unter Verwendung des Next.js-Frameworks. Darüber hinaus wird die visuelle Komponentenbibliothek Chakra UI verwendet, die das Atomic Design-Konzept auf die erstellten Komponenten anwendet. Um mehr zu erfahren, besuchen Sie Crazystack.com.br.

Das obige ist der detaillierte Inhalt vonDas Übersetzen Ihres React-Projekts mit i war noch nie so einfach. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage