[英]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.