lingui库中的宏 t 在React上无法正常工作。

huangapple go评论116阅读模式
英文:

lingui library's macro t not working on react

问题

I use the latest library for translation, but the macro t not working, the <Trans> working fine.

To Reproduce

  1. open codesandbox
  2. yarn install
  3. yarn start
  4. click different language on the top of the screen

bug description:
only content in <Trans>content<Trans> will be translated, but the last content on {hello react} is not translated.

index.tsx:

  1. import React from 'react';
  2. import ReactDOM from 'react-dom/client';
  3. import reportWebVitals from './reportWebVitals';
  4. import { StoreProvider } from './components/store-provider';
  5. import createStore from './store';
  6. import { LanguageProvider } from './components/language-provider';
  7. import { LangSwitcher } from './components/lang-switcher';
  8. import { DataComponent } from './components/DataComponent';
  9. import { Trans, t } from '@lingui/macro';
  10. const store = createStore();
  11. const root = ReactDOM.createRoot(
  12. document.getElementById('root') as HTMLElement
  13. );
  14. root.render(
  15. <React.StrictMode>
  16. <StoreProvider store={store}>
  17. <LanguageProvider>
  18. <LangSwitcher />
  19. <p>
  20. <Trans>hello world</Trans>
  21. </p>
  22. <DataComponent data={t`hello react`} />
  23. </LanguageProvider>
  24. </StoreProvider>
  25. </React.StrictMode>
  26. );
  27. // If you want to start measuring performance in your app, pass a function
  28. // to log results (for example: reportWebVitals(console.log))
  29. // or send to an analytics endpoint.
  30. reportWebVitals();

package.json:

  1. {
  2. "name": "my-app",
  3. "version": "0.1.0",
  4. "private": true,
  5. "dependencies": {
  6. "@lingui/react": "^4.1.2",
  7. "@reduxjs/toolkit": "^1.9.5",
  8. "@testing-library/jest-dom": "^5.14.1",
  9. "@testing-library/react": "^13.0.0",
  10. "@testing-library/user-event": "^13.2.1",
  11. "@types/jest": "^27.0.1",
  12. "@types/node": "^16.7.13",
  13. "@types/react": "^18.0.0",
  14. "@types/react-dom": "^18.0.0",
  15. "make-plural": "^7.3.0",
  16. "react": "^18.2.0",
  17. "react-dom": "^18.2.0",
  18. "react-redux": "^8.0.5",
  19. "react-scripts": "5.0.1",
  20. "redux-persist": "^6.0.0",
  21. "redux-saga": "^1.2.3",
  22. "typescript": "^4.4.2",
  23. "web-vitals": "^2.1.0"
  24. },
  25. "scripts": {
  26. "start": "react-scripts start",
  27. "build": "react-scripts build",
  28. "test": "react-scripts test",
  29. "eject": "react-scripts eject",
  30. "extract": "lingui extract --clean",
  31. "compile": "lingui compile --strict"
  32. },
  33. "eslintConfig": {
  34. "extends": [
  35. "react-app",
  36. "react-app/jest"
  37. ]
  38. },
  39. "browserslist": {
  40. "production": [
  41. ">0.2%",
  42. "not dead",
  43. "not op_mini all"
  44. ],
  45. "development": [
  46. "last 1 chrome version",
  47. "last 1 firefox version",
  48. "last 1 safari version"
  49. ]
  50. },
  51. "devDependencies": {
  52. "@lingui/cli": "^4.1.2",
  53. "@lingui/macro": "^4.1.2"
  54. }
  55. }

lingui.config.ts:

  1. const linguiConfig = {
  2. catalogs: [
  3. {
  4. path: '<rootDir>/src/locales/{locale}/messages',
  5. include: ['<rootDir>/src'],
  6. },
  7. ],
  8. compileNamespace: 'cjs',
  9. fallbackLocales: {
  10. default: 'en-US',
  11. },
  12. format: 'po',
  13. formatOptions: {
  14. lineNumbers: false,
  15. },
  16. locales: [
  17. 'en-US',
  18. 'zh-CN',
  19. 'zh-TW',
  20. ],
  21. orderBy: 'messageId',
  22. rootDir: '.',
  23. runtimeConfigModule: ['@lingui/core', 'i18n'],
  24. sourceLocale: 'en-US',
  25. pseudoLocale: 'pseudo',
  26. }
  27. export default linguiConfig

tsconfig.json:

  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "lib": [
  5. "dom",
  6. "dom.iterable",
  7. "esnext"
  8. ],
  9. "allowJs": true,
  10. "skipLibCheck": true,
  11. "esModuleInterop": true,
  12. "allowSyntheticDefaultImports": true,
  13. "strict": true,
  14. "forceConsistentCasingInFileNames": true,
  15. "noFallthroughCasesInSwitch": true,
  16. "module": "esnext",
  17. "moduleResolution": "node",
  18. "resolveJsonModule": true,
  19. "isolatedModules": true,
  20. "noEmit": true,
  21. "jsx": "react-jsx",
  22. "baseUrl": "src"
  23. },
  24. "include": [
  25. "src"
  26. ]
  27. }
英文:

I use the latest library for translation, but the macro t not working, the &lt;Trans&gt; working fine.

To Reproduce

  1. open codesandbox
  2. yarn install
  3. yarn start
  4. click different language on the top of screen

bug description:
only content in &lt;Trans&gt;content&lt;Trans&gt; will translated, but the last content on {hello react} not translated.

index.tsx:

  1. import React from &#39;react&#39;;
  2. import ReactDOM from &#39;react-dom/client&#39;;
  3. import reportWebVitals from &#39;./reportWebVitals&#39;;
  4. import { StoreProvider } from &#39;./components/store-provider&#39;;
  5. import createStore from &#39;./store&#39;
  6. import { LanguageProvider } from &#39;./components/language-provider&#39;;
  7. import { LangSwitcher } from &#39;./components/lang-switcher&#39;;
  8. import { DataComponent } from &#39;./components/DataComponent&#39;;
  9. import { Trans, t } from &#39;@lingui/macro&#39;;
  10. const store = createStore();
  11. const root = ReactDOM.createRoot(
  12. document.getElementById(&#39;root&#39;) as HTMLElement
  13. );
  14. root.render(
  15. &lt;React.StrictMode&gt;
  16. &lt;StoreProvider store={store}&gt;
  17. &lt;LanguageProvider&gt;
  18. &lt;LangSwitcher /&gt;
  19. &lt;p&gt;
  20. &lt;Trans&gt;hello world&lt;/Trans&gt;
  21. &lt;/p&gt;
  22. &lt;DataComponent data={t`hello react`} /&gt;
  23. &lt;/LanguageProvider&gt;
  24. &lt;/StoreProvider&gt;
  25. &lt;/React.StrictMode&gt;
  26. );
  27. // If you want to start measuring performance in your app, pass a function
  28. // to log results (for example: reportWebVitals(console.log))
  29. // or send to an analytics endpoint.
  30. reportWebVitals();

package.json:

  1. {
  2. &quot;name&quot;: &quot;my-app&quot;,
  3. &quot;version&quot;: &quot;0.1.0&quot;,
  4. &quot;private&quot;: true,
  5. &quot;dependencies&quot;: {
  6. &quot;@lingui/react&quot;: &quot;^4.1.2&quot;,
  7. &quot;@reduxjs/toolkit&quot;: &quot;^1.9.5&quot;,
  8. &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
  9. &quot;@testing-library/react&quot;: &quot;^13.0.0&quot;,
  10. &quot;@testing-library/user-event&quot;: &quot;^13.2.1&quot;,
  11. &quot;@types/jest&quot;: &quot;^27.0.1&quot;,
  12. &quot;@types/node&quot;: &quot;^16.7.13&quot;,
  13. &quot;@types/react&quot;: &quot;^18.0.0&quot;,
  14. &quot;@types/react-dom&quot;: &quot;^18.0.0&quot;,
  15. &quot;make-plural&quot;: &quot;^7.3.0&quot;,
  16. &quot;react&quot;: &quot;^18.2.0&quot;,
  17. &quot;react-dom&quot;: &quot;^18.2.0&quot;,
  18. &quot;react-redux&quot;: &quot;^8.0.5&quot;,
  19. &quot;react-scripts&quot;: &quot;5.0.1&quot;,
  20. &quot;redux-persist&quot;: &quot;^6.0.0&quot;,
  21. &quot;redux-saga&quot;: &quot;^1.2.3&quot;,
  22. &quot;typescript&quot;: &quot;^4.4.2&quot;,
  23. &quot;web-vitals&quot;: &quot;^2.1.0&quot;
  24. },
  25. &quot;scripts&quot;: {
  26. &quot;start&quot;: &quot;react-scripts start&quot;,
  27. &quot;build&quot;: &quot;react-scripts build&quot;,
  28. &quot;test&quot;: &quot;react-scripts test&quot;,
  29. &quot;eject&quot;: &quot;react-scripts eject&quot;,
  30. &quot;extract&quot;: &quot;lingui extract --clean&quot;,
  31. &quot;compile&quot;: &quot;lingui compile --strict&quot;
  32. },
  33. &quot;eslintConfig&quot;: {
  34. &quot;extends&quot;: [
  35. &quot;react-app&quot;,
  36. &quot;react-app/jest&quot;
  37. ]
  38. },
  39. &quot;browserslist&quot;: {
  40. &quot;production&quot;: [
  41. &quot;&gt;0.2%&quot;,
  42. &quot;not dead&quot;,
  43. &quot;not op_mini all&quot;
  44. ],
  45. &quot;development&quot;: [
  46. &quot;last 1 chrome version&quot;,
  47. &quot;last 1 firefox version&quot;,
  48. &quot;last 1 safari version&quot;
  49. ]
  50. },
  51. &quot;devDependencies&quot;: {
  52. &quot;@lingui/cli&quot;: &quot;^4.1.2&quot;,
  53. &quot;@lingui/macro&quot;: &quot;^4.1.2&quot;
  54. }
  55. }

lingui.config.ts:

  1. const linguiConfig = {
  2. catalogs: [
  3. {
  4. path: &#39;&lt;rootDir&gt;/src/locales/{locale}/messages&#39;,
  5. include: [&#39;&lt;rootDir&gt;/src&#39;],
  6. },
  7. ],
  8. compileNamespace: &#39;cjs&#39;,
  9. fallbackLocales: {
  10. default: &#39;en-US&#39;,
  11. },
  12. format: &#39;po&#39;,
  13. formatOptions: {
  14. lineNumbers: false,
  15. },
  16. locales: [
  17. &#39;en-US&#39;,
  18. &#39;zh-CN&#39;,
  19. &#39;zh-TW&#39;,
  20. ],
  21. orderBy: &#39;messageId&#39;,
  22. rootDir: &#39;.&#39;,
  23. runtimeConfigModule: [&#39;@lingui/core&#39;, &#39;i18n&#39;],
  24. sourceLocale: &#39;en-US&#39;,
  25. pseudoLocale: &#39;pseudo&#39;,
  26. }
  27. export default linguiConfig

tsconfig.json:

  1. {
  2. &quot;compilerOptions&quot;: {
  3. &quot;target&quot;: &quot;es5&quot;,
  4. &quot;lib&quot;: [
  5. &quot;dom&quot;,
  6. &quot;dom.iterable&quot;,
  7. &quot;esnext&quot;
  8. ],
  9. &quot;allowJs&quot;: true,
  10. &quot;skipLibCheck&quot;: true,
  11. &quot;esModuleInterop&quot;: true,
  12. &quot;allowSyntheticDefaultImports&quot;: true,
  13. &quot;strict&quot;: true,
  14. &quot;forceConsistentCasingInFileNames&quot;: true,
  15. &quot;noFallthroughCasesInSwitch&quot;: true,
  16. &quot;module&quot;: &quot;esnext&quot;,
  17. &quot;moduleResolution&quot;: &quot;node&quot;,
  18. &quot;resolveJsonModule&quot;: true,
  19. &quot;isolatedModules&quot;: true,
  20. &quot;noEmit&quot;: true,
  21. &quot;jsx&quot;: &quot;react-jsx&quot;,
  22. &quot;baseUrl&quot;: &quot;src&quot;
  23. },
  24. &quot;include&quot;: [
  25. &quot;src&quot;
  26. ]
  27. }

答案1

得分: 3

Here is the translated content:

每当在React应用程序中使用t宏时,您应该(1) 使用useLingui()钩子将您的组件“订阅”到更改,或者(2) - 使用defineMessage宏定义一个以后使用的消息。它具有与t相同的签名,并返回一个可传递给i18n._MessageDescriptor

我建议您修改您的代码如下:

index.tsx:

  1. import React from "react";
  2. import ReactDOM from "react-dom/client";
  3. import reportWebVitals from "./reportWebVitals";
  4. import { StoreProvider } from "./components/store-provider";
  5. import createStore from "./store";
  6. import { LanguageProvider } from "./components/language-provider";
  7. import { LangSwitcher } from "./components/lang-switcher";
  8. import { DataComponent } from "./components/DataComponent";
  9. import { Trans } from "@lingui/macro";
  10. import { msg } from "@lingui/macro";
  11. const store = createStore();
  12. const root = ReactDOM.createRoot(
  13. document.getElementById("root") as HTMLElement
  14. );
  15. root.render(
  16. <React.StrictMode>
  17. <StoreProvider store={store}>
  18. <LanguageProvider>
  19. <LangSwitcher />
  20. <p>
  21. <Trans>hello world</Trans>
  22. </p>
  23. <DataComponent data={msg`hello react`} />
  24. </LanguageProvider>
  25. </StoreProvider>
  26. </React.StrictMode>
  27. );
  28. reportWebVitals();

DataComponent.tsx:

  1. import { MessageDescriptor } from "@lingui/core";
  2. import { useLingui } from "@lingui/react";
  3. type props = {
  4. data: MessageDescriptor;
  5. };
  6. export const DataComponent: React.FC<props> = ({ data }) => {
  7. const { i18n } = useLingui();
  8. return <p>{i18n._(data)}</p>;
  9. };

sandbox中进行了测试,效果如预期。

英文:

Whenever you use the t macro in a React application, you should (1) "subscribe" your component to changes using the useLingui() hook, or (2) - use the defineMessage macro to define a message for later use. It has the same signature as t and returns a MessageDescriptor that you can pass to i18n._.

I would suggest modifying your code as follows:

index.tsx:

  1. import React from &quot;react&quot;;
  2. import ReactDOM from &quot;react-dom/client&quot;;
  3. import reportWebVitals from &quot;./reportWebVitals&quot;;
  4. import { StoreProvider } from &quot;./components/store-provider&quot;;
  5. import createStore from &quot;./store&quot;;
  6. import { LanguageProvider } from &quot;./components/language-provider&quot;;
  7. import { LangSwitcher } from &quot;./components/lang-switcher&quot;;
  8. import { DataComponent } from &quot;./components/DataComponent&quot;;
  9. import { Trans } from &quot;@lingui/macro&quot;;
  10. import { msg } from &quot;@lingui/macro&quot;;
  11. const store = createStore();
  12. const root = ReactDOM.createRoot(
  13. document.getElementById(&quot;root&quot;) as HTMLElement
  14. );
  15. root.render(
  16. &lt;React.StrictMode&gt;
  17. &lt;StoreProvider store={store}&gt;
  18. &lt;LanguageProvider&gt;
  19. &lt;LangSwitcher /&gt;
  20. &lt;p&gt;
  21. &lt;Trans&gt;hello world&lt;/Trans&gt;
  22. &lt;/p&gt;
  23. &lt;DataComponent data={msg`hello react`} /&gt;
  24. &lt;/LanguageProvider&gt;
  25. &lt;/StoreProvider&gt;
  26. &lt;/React.StrictMode&gt;
  27. );
  28. reportWebVitals();

DataComponent.tsx:

  1. import { MessageDescriptor } from &quot;@lingui/core&quot;;
  2. import { useLingui } from &quot;@lingui/react&quot;;
  3. type props = {
  4. data: MessageDescriptor;
  5. };
  6. export const DataComponent: React.FC&lt;props&gt; = ({ data }) =&gt; {
  7. const { i18n } = useLingui();
  8. return &lt;p&gt;{i18n._(data)}&lt;/p&gt;;
  9. };

Tested in the sandbox and it works as expected.

huangapple
  • 本文由 发表于 2023年5月21日 11:10:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76298143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定