Используйте Reaction-i18next в компонентах класса с декораторами и HOC - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь реализовать i18n в своем проекте React, который также использует Redux с помощью react-i18next.

В этом проекте мы используем компоненты класса с декораторами.

ИзначальноЯ хотел попробовать react-i18next v10, но так как он опирается на хуки, и я не могу использовать их в компонентах класса, для меня это не подлежит обсуждению.

Возвращаясь к устаревшей версии 9, я последовал шагпошаговое руководство (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, с withNamespaces() HOC, но с синтаксисом декоратора
@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 на моем компонентекласс, но тогда у меня нет {t, i18n} в реквизит компонента и, следовательно, не могу ничего перевести. Более того, указанный URL в ошибке, к сожалению, больше не существует.

Как я понял из документации, <I18nextProvider> должен передавать значения {t, i18n} в дерево компонентов, которого нет вмой случай.

Я застрял между неспособностью использовать v10 (у нас есть много компонентов, и я не могу просто преобразовать их все в функциональные компоненты в настоящее время) и неспособностью сделать v9работать либо.

У меня заканчиваются варианты, и я мог бы воспользоваться некоторым задним числом, если вы когда-либо сталкивались с подобными проблемами.

Заранее спасибо.

1 Ответ

0 голосов
/ 21 октября 2019

Для всех, кто интересуется, я заработал, обернув дочерний элемент <RootContainer> вместо обертывания самого <RootContainer> в методе рендеринга, что оставляет мне что-то вроде следующего:

  • Рендерер
ReactDOM.render(
    <Provider store={store}>
        <Router history={history}>
            <RootContainer />
        </Router>
    </Provider>,
    $root,
);
  • RootContainer
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>
        );
    }
}
  • SimpleElement
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). Может быть, это связано с рендерингом, не уверен, но все равно работает так, как задумано.

...