我正在尝试在我的React项目中实现i18n,该项目在react-i18next
的帮助下也使用Redux。
在此项目中,我们将类组件与装饰器一起使用。
最初,我想尝试react-i18next
v10,但由于它依赖于钩子,而且我不能在类组件中使用钩子,所以对我来说这是不可能的。
回到旧版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,
);
RootContainer
HOC包装了一个简单的组件,它是withNamespaces()
的子组件,但具有装饰器语法@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)
问题是,如果我删除了组件类上的@withNamespaces()
HOC,我将不再遇到此错误,但是组件的props中没有{t, i18n}
,因此无法翻译任何内容。
而且,不幸的是,错误中的给定URL不再存在。
据我从文档中了解到,<I18nextProvider>
应该将{t, i18n}
值传递到组件树下,这在我看来不是。
我发现自己陷入了无法使用v10(我们有很多组件,而现在不能将它们全部重构为功能组件)和无法使v9正常工作之间的困扰。
如果您遇到类似的问题,我的选择将用光,并且可以事后考虑。
谢谢。
答案 0 :(得分:0)
对于任何想知道的人,我都通过将<RootContainer>
子对象包装而不是将<RootContainer>
本身包装在renderer方法中来工作,这给我留下了类似以下内容:
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,
});
}
}
唯一的区别是我的渲染器本身是一个函数,而不是一个组件,而RootContainer
是一个成熟的React组件(准确地说是PureComponent)。不确定,这可能与渲染链接有关,但是它仍然可以按预期的方式工作。
答案 1 :(得分:0)
我这样做是设法在课堂上使用了react-i18next的最新版本:
import { withTranslation } from 'react-i18next';
class RootContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
<span>{this.props.t('Home')}</span>
}
}