>  기사  >  웹 프론트엔드  >  i를 사용하여 React 프로젝트를 번역하는 것이 그 어느 때보다 쉬워졌습니다.

i를 사용하여 React 프로젝트를 번역하는 것이 그 어느 때보다 쉬워졌습니다.

王林
王林원래의
2024-08-24 11:04:05592검색

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

미친 개발자라고 말해 보세요!

오늘 저는 전체 프로젝트를 React로 변환하는 것이 오늘날 그 어느 때보다 쉬웠던 적이 없다는 것을 보여 드리겠습니다. 하지만 먼저 이것이 왜 중요한지 알아야 합니다.

사람들이 프로그래밍을 시작할 때 코드 텍스트와 메시지가 포르투갈어(pt-BR)로 되어 있는 것이 일반적입니다. 프로젝트를 다른 언어로 번역하는 것은 결코 우선순위가 아니며 복잡하거나 불필요한 것으로 간주됩니다.

그렇다면 왜 관련이 있을까요?

현실에 따라 다릅니다. 이 프로세스를 고려해야 하는 몇 가지 이유는 다음과 같습니다.

회사에 필요해요
귀하가 일하는 회사나 귀하가 보유한 일부 SaaS가 다른 국가에서 운영을 시작하고 이러한 요구가 있을 수 있습니다. 이 기능을 갖춘 제품은 큰 차이가 있습니다.

해외 공석 지원
국제 공석에 지원하는 경우 이미 국제화된 프로젝트가 포함된 포트폴리오를 보유하면 눈에 띄는 하이라이트를 얻을 수 있습니다. 이는 귀하가 글로벌 프로젝트에 참여할 준비가 되어 있고 대부분의 사람들처럼 게으르지 않다는 것을 보여줍니다.

너무 많은 것을 배울 수는 없습니다
국제화는 단순한 기능이 아니라 중요한 학습 경험이기도 합니다. 이것은 여러분의 기술과 도구에 포함시킬 수 있는 또 다른 무기입니다.

과거에는 어떻게 이루어졌나요?

프로젝트 번역은 이미 오래된 문제입니다. 사람들은 HTML에서 국가 국기를 선택하여 선택하고 어떤 텍스트가 표시될지 알 수 있는 코드로 채웠습니다.
매우 무시되었습니다. 웹사이트는 단일 언어로 만들어졌고, 번역은 닥치는 대로 추가되었습니다. 백엔드에 있었다면 거래는 더욱 악화되었을 것입니다.

인터넷이 세계화됨에 따라 다국어 소프트웨어에 대한 수요가 증가하면서 i18n을 위한 특정 도구가 등장했습니다. GNU Gettext와 같은 솔루션이 백엔드에 등장했고, 그 뒤를 이어 i18next와 같은 libs 및 프론트엔드용 React-intl이 등장했습니다. 여기서 의문이 듭니다...

i18next vs. React-intl: 어느 것을 선택할 것인가?

  • i18next: 이 패키지는 2011년에 등장했으며 클라이언트측 Node.js와 SPA 모두에서 작동하는 npm 패키지였습니다. 커뮤니티에서는 이를 채택하여 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. 구성: i18next를 구성하려면 i18n.js를 생성하세요.
   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. 번역: 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 프로젝트에서 무엇을 했는지 보여드리겠습니다. 먼저 프로젝트 자체의 공용 폴더에 정의한 정적 JSON을 사용하여 Nextjs에서 다른 구성을 만들었습니다! 살펴보세요:

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. 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.

첫 번째 애플리케이션에서는 Node.js 생태계에서 REST API를 구축하는 방법을 배우게 됩니다. 사용 가능한 시간 나열, 예약된 약속에서 주문 생성, 충성도 시스템, 커미션, 지불, 고객 리뷰 등과 같은 복잡한 비즈니스 규칙과 관련된 사용 사례가 생성됩니다. 모든 작업은 TypeScript에서 수행되었으며 비관계형 데이터베이스 MongoDB를 사용했습니다.

두 번째 애플리케이션에서는 React.js 생태계에 관리 패널을 구축하여 그래프를 보고 기록을 조작하는 방법을 배우게 됩니다. 모두 TypeScript와 Next.js 프레임워크를 사용하여 수행되었습니다. 또한, 생성된 컴포넌트에 Atomic Design 개념을 적용하여 Chakra UI 비주얼 컴포넌트 라이브러리를 사용합니다. 자세한 내용을 알아보려면 crazystack.com.br을 방문하세요.

위 내용은 i를 사용하여 React 프로젝트를 번역하는 것이 그 어느 때보다 쉬워졌습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.