簡體   English   中英

在帶有裝飾器和 HOC 的 class 組件中使用 react-i18next

[英]Use react-i18next in class components with decorators and HOC

我正在嘗試在我的 React 項目中實現 i18n,該項目還借助react-i18next

在這個項目中,我們使用帶有裝飾器的 class 組件。

最初,我想嘗試react-i18next v10,但由於它依賴於鈎子,我不能在 class 組件中使用這些鈎子,所以這對我來說是不可能的。

回到舊版 v9,我按照分步指南( https://react.i18next.com/legacy-v9/step-by-step-guide )執行了以下步驟:

  • 創建了帶有翻譯的i18n.js配置文件
  • i18nextProvider包裹我的根容器
ReactDOM.render(
    <Provider store={store}>
        <Router history={history}>
            <I18nextProvider i18n={i18n}>
                <RootContainer />
            </I18nextProvider>
        </Router>
    </Provider>,
    $root,
);
  • 使用withNamespaces() HOC 包裝了一個簡單的組件,它是RootContainer的子組件,但使用了裝飾器語法
@withNamespaces()
export default class SimpleComponent extends React.PureComponent {
    // (... component class code ...)
}

沒有裝飾器的情況等同於以下內容:

class SimpleComponent extends React.PureComponent {
    // (... component class code ...)
}
export default withNamespaces()(SimpleComponent);

我必須遺漏一些東西,因為我在 SSR 期間收到以下錯誤:

react-i18next:: You will need pass in an i18next instance either by props, using I18nextProvider or by using i18nextReactModule. Learn more https://react.i18next.com/components/overview#getting-the-i-18-n-function-into-the-flow
0|ssr-dev  | TypeError: Cannot read property 'wait' of null
0|ssr-dev  |     at NamespacesConsumerComponent.render (/client/node_modules/react-i18next/dist/commonjs/NamespacesConsumer.js:220:33)

問題是,如果我刪除組件 class 上的@withNamespaces() HOC,我將不再出現此錯誤,但是組件的 props 中沒有{t, i18n} ,因此無法翻譯任何內容。 此外,不幸的是,錯誤中給定的 URL 不再存在。

正如我從文檔中了解到的那樣, <I18nextProvider>應該將{t, i18n}值向下傳遞到組件樹,這不是我的情況。

我發現自己陷入了無法使用 v10(我們有很多組件,目前我不能將它們全部重構為功能組件)和無法使 v9 正常工作之間。

如果您遇到類似的問題,我的選擇已經不多了,可以使用后見之明。

提前致謝。

通過這樣做,我設法在 class 中使用了最新版本的 react-i18next:

import { withTranslation } from 'react-i18next';

class RootContainer extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
   <span>{this.props.t('Home')}</span>
  }
}

對於任何想知道的人,我通過包裝<RootContainer>孩子而不是在渲染器方法中包裝<RootContainer>本身來使其工作,這給我留下了如下內容:

  • 渲染器
ReactDOM.render(
    <Provider store={store}>
        <Router history={history}>
            <RootContainer />
        </Router>
    </Provider>,
    $root,
);
  • 根容器
import i18n from "../core/translations/i18n";
import {I18nextProvider} from "react-i18next";

@connectWithStore(mapStateToProps, mapActionsToProps)
export default class RootContainer extends React.PureComponent {
    // (... class code ...)

    render {
        return (
            <I18nextProvider i18n={i18n}>
                <div>
                    <SimpleComponent/>
                </div>
            </I18nextProvider>
        );
    }
}
  • 簡單元素
import {withNamespaces} from "react-i18next";

@withNamespaces()
export default class SimpleComponent extends React.PureComponent {
    // (... class code ...)

    componentDidMount() {
        // Successfully logging the values below
        console.warn("Got i18n props?", {
            t: this.props.t,
            i18n: this.props.i18n,
        });
    }
}

唯一的區別是我的渲染器是 function,而不是組件本身,而RootContainer是一個成熟的 React 組件(准確地說是 PureComponent)。 也許它與渲染鏈接有關,不確定,但它仍然按預期方式工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM