First of all thanks for the example! https://github.com/i18next/react-i18next/blob/master/example/nextjs
I'm wondering what is the best practice to access t inside nested components?
For example if we have SomeComponent inside myComponent:
// pages/index.js
function myComponent({ t}) {
return (
<div>
{t('welcome')}
<p>{t('integrates_react-i18next')}</p>
<SomeComponent>
</div>
);
}
would it be better to pass t as a prop to the SomeComponent or use the HOC translate()(SomeComponent).
Also, should we set:
// Passing down initial translations
// use req.i18n instance on serverside to avoid overlapping requests set the language wrong
Extended.getInitialProps = async ({ req }) => {
if (req && !process.browser) {
req.i18n.toJSON = () => null; // do not serialize i18next instance and send to client
const initialI18nStore = {};
req.i18n.languages.forEach((l) => {
initialI18nStore[l] = req.i18n.services.resourceStore.data[l];
});
return {
i18n: req.i18n, // use the instance on req - fixed language on request (avoid issues in race conditions with lngs of different users)
initialI18nStore,
initialLanguage: req.i18n.language,
};
}
return {};
};
only in the parent (page) component or each time we use translate HOC?
good question...even on our larger projects we never came to a real conclusion...we basically do both...with a tendence to use the hoc on bigger components while just passing down t as prop for smaller - but there is no real best practice...more a matter of taste.
Extending the getInitialProps is only needed on page level components -> all children get the i18n set to context from the wrapping translate hoc -> so inner translate hoc get the i18n instance set via context and need not getting it initially set via props.
so basically for the "page" components:
const Extended = translate('translation', { i18n, wait: process.browser })(PageComponent);
+
Extended.getInitialProps ...
and for its children
const Extended = translate()(PageComponentsNLevelChild);
will be enough because i18n instance and wait param will come from the parent, am I right?
yes...correct
just extended the sample like suggested by you: https://github.com/i18next/react-i18next/commit/a212eda5991a54f4bed3f48bf3869a22b5ede9fd
I have a follow up question. As per the documentation the Translate component also marks the wrapped component for a re-render in case of a change in language or translations.
Now if ONLY my parent component is wrapped in the HOC and I am passing the t function as a prop to all it's child/grandchild components.
I am assuming the child components will also re-render as part of the re-render for the parent component on any language/translation changes. Is that correct?
yes...t function itself is also a new function...will rerender the whole tree.
Most helpful comment
good question...even on our larger projects we never came to a real conclusion...we basically do both...with a tendence to use the hoc on bigger components while just passing down t as prop for smaller - but there is no real best practice...more a matter of taste.
Extending the getInitialProps is only needed on page level components -> all children get the i18n set to context from the wrapping translate hoc -> so inner translate hoc get the i18n instance set via context and need not getting it initially set via props.