在类组件中使用 react-i18next
Posted
技术标签:
【中文标题】在类组件中使用 react-i18next【英文标题】:Using react-i18next within a class component 【发布时间】:2019-07-13 07:00:20 【问题描述】:我正在尝试使用 react-i18next 翻译我的应用程序。我知道如何将它与简单的 const 组件一起使用,但不是在一个类中。
我正在使用 I18nextProvider。这是我的 App.js 文件。
import React, Component from 'react';
import Provider from 'react-redux';
import BrowserRouter from 'react-router-dom';
import I18nextProvider from 'react-i18next';
import i18next from 'i18next';
// eslint-disable-next-line import/no-extraneous-dependencies
import hot from 'react-hot-loader';
import 'bootstrap/dist/css/bootstrap.css';
import '../../scss/app.scss';
import Router from './Router';
import store from './store';
import ScrollToTop from './ScrollToTop';
import config as i18nextConfig from '../../translations';
i18next.init(i18nextConfig);
class App extends Component
constructor()
super();
this.state =
loading: true,
loaded: false,
;
componentDidMount()
window.addEventListener('load', () =>
this.setState( loading: false );
setTimeout(() => this.setState( loaded: true ), 500);
);
render()
const loaded, loading = this.state;
return (
<Provider store=store>
<BrowserRouter basename="/easydev">
<I18nextProvider i18n=i18next>
<ScrollToTop>
!loaded &&
<div className=`load$loading ? '' : ' loaded'`>
<div className="load__icon-wrap">
<svg className="load__icon">
<path fill="#4ce1b6" d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" />
</svg>
</div>
</div>
<div>
<Router />
</div>
</ScrollToTop>
</I18nextProvider>
</BrowserRouter>
</Provider>
);
export default hot(module)(App);
现在在基于 const 的组件中使用它非常容易。这是一个例子:
import React from 'react';
import Card, CardBody, Col from 'reactstrap';
import HeartOutlineIcon from 'mdi-react/HeartOutlineIcon';
import translate from 'react-i18next';
import PropTypes from 'prop-types';
const InfoCard = ( t ) => (
<Col md=12 xl=3 lg=6 sm=12 xs=12>
<Card>
<CardBody className="dashboard__health-chart-card">
<div className="card__title">
<h5 className="bold-text">t('dashboard_fitness.heartrate')</h5>
</div>
<div className="dashboard__health-chart">
<div className="dashboard__health-chart-info">
<HeartOutlineIcon style= fill: '#ff4861' />
<p className="dashboard__health-chart-number">96</p>
<p className="dashboard__health-chart-units">b/min</p>
</div>
</div>
</CardBody>
</Card>
</Col>
);
InfoCard.propTypes =
t: PropTypes.func.isRequired,
;
export default translate('common')(InfoCard);
如您所见,我只是从 react-i18next 导入翻译,我几乎准备好使用 t 函数。
如何在类组件中实现相同的功能?我想在这个类中实现它:
/* eslint-disable react/no-typos */
import React, PureComponent from 'react';
import DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown from 'reactstrap';
import translate from 'react-i18next';
import MenuDownIcon from 'mdi-react/ChevronDownIcon';
import MagnifyIcon from 'mdi-react/MagnifyIcon';
class TradesTableControls extends PureComponent
constructor()
super();
this.state =
rows: 10,
;
changeRowAmount = (rows) =>
switch (rows)
case 10:
this.setState( rows: 10 );
break;
case 25:
this.setState( rows: 25 );
break;
case 50:
this.setState( rows: 50 );
break;
case 100:
this.setState( rows: 100 );
break;
default:
this.setState( rows: 10 );
break;
;
render()
return (
<div className="trades-table__controls-wrap">
<div className="trades-table__controls">
<UncontrolledDropdown>
<DropdownToggle className="icon icon--right" outline size="sm">
<p>
t('history.controls.show')
this.state.rows
t('history.controls.results')
<MenuDownIcon />
</p>
</DropdownToggle>
<DropdownMenu className="dropdown__menu">
<DropdownItem onClick=() => this.changeRowAmount(10)>10</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(25)>25</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(50)>50</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(100)>100</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
<div className="trades-table__controls-right">
<div className="trades-table__control-search">
<input placeholder="Search" />
<div className="trades-table__control-search-icon"><MagnifyIcon /></div>
</div>
</div>
</div>
);
export default translate('common')(TradesTableControls);
我对 React 和 ES6 还很陌生,但是我无法在线找到解决方案。非常感谢任何帮助!
谢谢!
【问题讨论】:
【参考方案1】:目前(即 2021 年)文档建议打包 HOC withTranslation()
:
import React from 'react';
import withTranslation from 'react-i18next';
class MyComponent extends Component
return <p>this.props.t('key')</p>
export default withTranslation()(MyComponent);
如果您喜欢使用 命名空间,请导出:
export default withTranslation('namespace')(MyComponent);
参考:官方docs。
【讨论】:
【参考方案2】:就像t
可以作为functional
组件中的道具使用一样,您可以在用translate HOC
包装TradesTableComponent
后从类组件中的props
访问它。你需要做的就是destructure
它来自渲染方法中的道具,比如
const t = this.props;
相关代码
render()
const t = this.props;
return (
<div className="trades-table__controls-wrap">
<div className="trades-table__controls">
<UncontrolledDropdown>
<DropdownToggle className="icon icon--right" outline size="sm">
<p>
t('history.controls.show')
this.state.rows
t('history.controls.results')
<MenuDownIcon />
</p>
</DropdownToggle>
<DropdownMenu className="dropdown__menu">
<DropdownItem onClick=() => this.changeRowAmount(10)>10</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(25)>25</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(50)>50</DropdownItem>
<DropdownItem onClick=() => this.changeRowAmount(100)>100</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
<div className="trades-table__controls-right">
<div className="trades-table__control-search">
<input placeholder="Search" />
<div className="trades-table__control-search-icon"><MagnifyIcon /></div>
</div>
</div>
</div>
);
【讨论】:
【参考方案3】:这是一个工作示例,说明如何在 React Native 的基于类的组件中使用 translation
。
import withTranslation from 'react-i18next';
class PersonalScreen extends React.Component
render()
const t = this.props;
return (
<Text>t('Translate this text')</Text>
)
export default withTranslation()(PersonalScreen)
【讨论】:
我使用了@Mathissimo 的答案,但是从this.props 中提取t 我不需要在JSX 中进行任何更改,非常好! -const t = this.props;
【参考方案4】:
这是一个如何使用 i18next + React + Typescript 和类定义https://gitlab.com/damjan89/i18next-typescript-example的示例
【讨论】:
@liquid_boy 通常,我们会被要求直接在 *** 上的帖子中提供答案。我们可以提供指向包含更多详细信息的页面的链接,但解决方案的要点应该在帖子中。此外,在该链接之后,我找到了一个包含所有基本内容的项目来进行本地化,但组件本身没有示例。最后一点不见了。 我在一个类中需要这个包,我用它来制作与 API 相关的函数。从上面的 repo 中,我找到了对我有帮助的代码。import i18next from 'i18next';
i18next.t('someKey');
谢谢以上是关于在类组件中使用 react-i18next的主要内容,如果未能解决你的问题,请参考以下文章