Using react-i18next within a class component
Solution 1
Just like t
is available as props in a functional
component, you can access it from props
in a class component after wrapping TradesTableComponent
with translate HOC
. All you need to do is destructure
it from props in render method like
const { t } = this.props;
Relevant code
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>
);
}
Solution 2
Currently (ie 2021) the docs suggest the packaged 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);
If you like to use namespaces then export:
export default withTranslation('namespace')(MyComponent);
Ref: official docs.
Solution 3
Here's a working example of how to use translation
in a class-based component in React Native.
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)
Related videos on Youtube
Alexander Valtingojer
Updated on June 04, 2022Comments
-
Alexander Valtingojer almost 2 years
I am trying to translate my application using react-i18next. I know how to use it with simple const components, but not within a class.
I'm working with the I18nextProvider. This is my App.js file.
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);
Now using it within a const based component is quite easy. Here is an example:
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);
As you can see I just import the translate from the react-i18next and I'm almost ready to go with the t function.
How can I achieve the same within a class component? I want to implement it in this class:
/* 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);
I'm quite new to React and ES6, but I was unable to find the solution online. Would really appreciate any help!
Thanks!
-
Jean-François Beauchamp almost 4 years@liquid_boy Normally, we are asked to provide the answer directly in our posts on StackOverflow. We can provide a link directing to a page with more details, but the gist of the solution should be in the post. Also, following that link I found a project with all the basic stuff to do localization, but there is no example in the component itself. The last bit is missing.
-
Fernando Tholl over 3 yearsI used the answer from @Mathissimo, but extracting t from this.props I didn't need to change anything in JSX, very good! -
const { t } = this.props;
-
shery089 over 2 yearsI needed this package in a class which I was using to make API related functions. From the above repo, I have found this code which helped me.
import i18next from 'i18next';
i18next.t('someKey');
Thanks