오늘 저는 전체 프로젝트를 React로 변환하는 것이 오늘날 그 어느 때보다 쉬웠던 적이 없다는 것을 보여 드리겠습니다. 하지만 먼저 이것이 왜 중요한지 알아야 합니다.
사람들이 프로그래밍을 시작할 때 코드 텍스트와 메시지가 포르투갈어(pt-BR)로 되어 있는 것이 일반적입니다. 프로젝트를 다른 언어로 번역하는 것은 결코 우선순위가 아니며 복잡하거나 불필요한 것으로 간주됩니다.
현실에 따라 다릅니다. 이 프로세스를 고려해야 하는 몇 가지 이유는 다음과 같습니다.
회사에 필요해요
귀하가 일하는 회사나 귀하가 보유한 일부 SaaS가 다른 국가에서 운영을 시작하고 이러한 요구가 있을 수 있습니다. 이 기능을 갖춘 제품은 큰 차이가 있습니다.
해외 공석 지원
국제 공석에 지원하는 경우 이미 국제화된 프로젝트가 포함된 포트폴리오를 보유하면 눈에 띄는 하이라이트를 얻을 수 있습니다. 이는 귀하가 글로벌 프로젝트에 참여할 준비가 되어 있고 대부분의 사람들처럼 게으르지 않다는 것을 보여줍니다.
너무 많은 것을 배울 수는 없습니다
국제화는 단순한 기능이 아니라 중요한 학습 경험이기도 합니다. 이것은 여러분의 기술과 도구에 포함시킬 수 있는 또 다른 무기입니다.
프로젝트 번역은 이미 오래된 문제입니다. 사람들은 HTML에서 국가 국기를 선택하여 선택하고 어떤 텍스트가 표시될지 알 수 있는 코드로 채웠습니다.
매우 무시되었습니다. 웹사이트는 단일 언어로 만들어졌고, 번역은 닥치는 대로 추가되었습니다. 백엔드에 있었다면 거래는 더욱 악화되었을 것입니다.
인터넷이 세계화됨에 따라 다국어 소프트웨어에 대한 수요가 증가하면서 i18n을 위한 특정 도구가 등장했습니다. GNU Gettext와 같은 솔루션이 백엔드에 등장했고, 그 뒤를 이어 i18next와 같은 libs 및 프론트엔드용 React-intl이 등장했습니다. 여기서 의문이 듭니다...
i18next: 이 패키지는 2011년에 등장했으며 클라이언트측 Node.js와 SPA 모두에서 작동하는 npm 패키지였습니다. 커뮤니티에서는 이를 채택하여 2015년에 마침내 React-i18next lib에 React 버전을 만들었습니다. 따라서 긍정적인 점과 부정적인 점은 다음과 같습니다.
react-intl: FormatJS 프로젝트의 일부로 국제 JavaScript API 표준을 따르며 최신 브라우저와의 호환성을 보장합니다.
i18다음 내 친구들! 시작하려면 항상 문서를 읽는 것을 권장하지만 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;
물론 아닙니다. 이제 제가 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를 만들었습니다. 수입을 시작으로
import { useTranslation } from "react-i18next"; import { createContext, useState, useContext } from "react";
const I18NContext = createContext({} as any);
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.
첫 번째 애플리케이션에서는 Node.js 생태계에서 REST API를 구축하는 방법을 배우게 됩니다. 사용 가능한 시간 나열, 예약된 약속에서 주문 생성, 충성도 시스템, 커미션, 지불, 고객 리뷰 등과 같은 복잡한 비즈니스 규칙과 관련된 사용 사례가 생성됩니다. 모든 작업은 TypeScript에서 수행되었으며 비관계형 데이터베이스 MongoDB를 사용했습니다.
두 번째 애플리케이션에서는 React.js 생태계에 관리 패널을 구축하여 그래프를 보고 기록을 조작하는 방법을 배우게 됩니다. 모두 TypeScript와 Next.js 프레임워크를 사용하여 수행되었습니다. 또한, 생성된 컴포넌트에 Atomic Design 개념을 적용하여 Chakra UI 비주얼 컴포넌트 라이브러리를 사용합니다. 자세한 내용을 알아보려면 crazystack.com.br을 방문하세요.
위 내용은 i를 사용하여 React 프로젝트를 번역하는 것이 그 어느 때보다 쉬워졌습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!