React-i18next: infinite loop with dynamically nested components

Created on 16 Aug 2017  路  12Comments  路  Source: i18next/react-i18next

Hi,
I've got a browser-crashing scenario with some nested components where translate is called on an inner and outer component. I guess it's some weird edge-case with context handling.

I've tried to dumb it down quite a bit:

OuterComponent renders MiddleComponent and passes an anonymous Component that renders InnerComponent with some extra parameter.
OuterComponent and InnerComponent are translated.

I'm sorry that this is still so complex, but I couldn't get this any more simple.

Is this a bug in react-i18next? Is it something in react itself?

import * as React from 'react';
import {translate, Trans} from 'react-i18next';

const InnerComponent = translate()(
    ({name}: { name: string }) => <Trans>some-test</Trans>
);

const MiddleComponent =  ({Component}: { Component: React.ComponentType }) => <div><Component /></div> ;

const OuterComponent = translate()(
    class extends React.Component<any> {
        render() {
            console.log('this loops like crazy...');
            return (
                <div>
                    <MiddleComponent Component={() => <InnerComponent name="qwe"/>}/>
                </div>
            );
        }
    }
);

Most helpful comment

hm...must be some weird timing issue...but honestly no exact idea why

the cache does add resource bundles and cause of that triggers a few times added - as we listen to added and trigger a rerender upon that this might be to much....?!?

could you try setting bindStore to false?

translate('yourNS', { bindStore: false })(OuterComponent)

All 12 comments

did you try setting wait flag on outerComponent?

translate('yourNS', { wait: true })(OuterComponent) ?

unfortunately that doesn't change the behaviour :/

hm...not having that in my webpackbin: https://www.webpackbin.com/bins/-Krf0-JAwpI7p-RycK2q

do you spot a difference?

I've been trying to reduce my project and there are several differences

  • I'm not rendering instantly, but only when i18next has finished loading - if I render instantly, it seems to work
  • I'm using the i18next-localstorage-cache plugin. It seems that the problem disappears as soon as I remove that plugin

but now I'm at an impasse - I can make the problem go away when I don't use the cache, but I can't reproduce it in your webpackbin :/

hm...must be some weird timing issue...but honestly no exact idea why

the cache does add resource bundles and cause of that triggers a few times added - as we listen to added and trigger a rerender upon that this might be to much....?!?

could you try setting bindStore to false?

translate('yourNS', { bindStore: false })(OuterComponent)

I'll try that next week - currently I'm on vacation.

thanks...and have a nice holiday

Adding bindStore: false to the translate call of OuterComponent seems to mitigate the problem.

Is this guaranteed to work when specifiying it once in the outermost layer for deeper nesting or is it possible to set this as default value somewhere so that I don't have to repeat that option everywhere?

https://react.i18next.com/components/translate-hoc.html#set-defaults-for-all-your-translate-hoc-components

Oh, nice. I was still at 4.7.0 which didn't have that option.
Had not noticed that this was getting so many updates :)

yup, also works as a default options. thank you very much - your reaction times are amazing :)

reaction time will even get better as soon we got more customers using our localization as a service offering https://locize.com ;)

Was this page helpful?
0 / 5 - 0 ratings