-
Notifications
You must be signed in to change notification settings - Fork 390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: do not remount children of I18nProvider #1501
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
size-limit report 📦
|
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## next #1501 +/- ##
==========================================
- Coverage 75.75% 75.06% -0.70%
==========================================
Files 79 79
Lines 1980 1961 -19
Branches 516 513 -3
==========================================
- Hits 1500 1472 -28
- Misses 360 372 +12
+ Partials 120 117 -3
... and 17 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
the idiomatic way to make it rerender in component is function MyComponent() {
const i18n = useLingui();
t(i18n)`My Message`;
} But it's quite verbose and actually is enough to just use function MyComponent() {
useLingui(); // <-- will subscribe this component for the locale changes
t`My Message`; // <-- uses global i18n instance
} i actually thinking of creating an additional macro, similar to function MyComponent() {
const {t} = useLingui(); // <-- imported from @lingui/macro
t`My Message`;
} This will use i18n instance from components tree, automatically subscribe for changes and in general less error-prone. But tranformation of this macro is a bit tricky from AST perspective, because you need to traverse scope in both directions (babel-macro-plugin limitations) |
Could you document that change in a migration guide? |
1368562
to
15c3a98
Compare
big, big thanks for updating other outdated pages as well! |
15c3a98
to
e53823a
Compare
d19665d
to
898ac86
Compare
website/docs/releases/migration-4.md
Outdated
### I18nProvider no longer remounts its children on locale change | ||
|
||
Previously, the `I18nProvider` remounted its children on locale change. This ensured that the whole app was re-rendered with the new locale and all strings were rendered correctly translated. | ||
Apart from not being very performant, this approach had the drawback that the state of the app was lost - all components were re-mounted and their state was reset. This is not a standard behavior of React Context providers and could cause some confusion. | ||
|
||
In v4, the `I18nProvider` no longer remounts its children on locale change. Instead, when locale changes, the context value provided by `I18nProvider` is updated and all components that consume the provided React Context are re-rendered with the new locale. | ||
This includes components provided by Lingui, such as `Trans` or `Plural` and also custom components that use the `useLingui` hook. | ||
|
||
This is the default behavior, but you can disable it by setting `forceRenderOnLocaleChange={false}`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any way to turn v3 behaviour for transition period? As far as i understand, forceRenderOnLocaleChange={false}
will not make it as in v3, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked the code one more time and question arised. What is the value of forceRenderOnLocaleChange=false
? I could not imagine a usecase where user will not want to have application to react to the locale changes.
I think the previous behaviour of this flag was indeed confusing and some people wanted to disable it, that's why this flag exists. But with current implementation, is it better to delete it completely? Or make this flag kinda enabling v3 compatibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @thekip I'm not sure about the history of the code and why forceRenderOnLocaleChange
was added TBH.
I guess someone had some use case for the I18nProvider
to not do anything "clever" but only pass the i18n object down.
I think a good way forward would be to remove the forceRenderOnLocaleChange
prop, have the I18nProvider
behave as if forceRenderOnLocaleChange={true}
AND export the LinguiContext
so that people can build their own context providers where they can do whatever they want.
This will make the usual thing easy to do, and harder / unusual things possible (the v3 behavior, for example - whatever it was 😄).
Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1194 - might be related
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export the LinguiContext so that people can build their own context providers
I always thought that exporting context directly from the lib is not a good thing. At least i haven't seen such examples in big projects.
Usually, libs give more high level primitives to work with. Such as usLingui()
hook. What could be done with exported Context what couldn't be done with just useLingui
hook? (sorry, I'm not too much into React)
I think a good way forward would be to remove the forceRenderOnLocaleChange prop
What stopping us from deleting it in this PR? I don't see a value of this anymore.
I also a bit worried about transition path. If someone rely on the forceRenderOnLocaleChange
in v3, for transition to v4, should go and find all places where unsafe t
(and other from core
) macro calls are used and add a useLingui hook. That might be quite a blocking factor for adopting v4. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always thought that exporting context directly from the lib is not a good thing. At least i haven't seen such examples in big projects.
Would be nice to not have to do that but I don't think it does a lot of harm (it's just an exported object) and it gives users the flexibility to do anything they want.
Here are some examples that export the Context: react-redux, mobx-react (no longer having own context) - these are pretty big projects.
Usually, libs give more high level primitives to work with
yes, and we give the I18nProvider
which should cover the usual cases. And useLingui()
which works fine as-is.
If our I18nProvider
does not suit someone well, and the LinguiContext
is exported, we're not blocking users to do whatever they please. When someone encounters a problem with I18nProvider
and opens an issue, a solution can be found if the LinguiContext
can be used by developers (Then they can share their custom I18nProvider
and perhaps we can integrate it in the next version).
If we don't export the LinguiContext
then we're blocking people from making custom solutions possible. At the same time, exporting it doesn't mean maintenance problems for the lib afaict.
What could be done with exported Context what couldn't be done with just useLingui hook?
Well, this whole question concerns the I18nProvider
, not really the useLingui
hook which works fine. But to answer "what can be done with with exported Context". The answer is that anything can be done. People use open source software in ways that a maintainer cannot always anticipate and I think it's best not to block people from doing what they want unless it has maintenance burden (exporting one Context object is not a maintenance burden).
If you want a more specific example I think I can come up with something :).
What stopping us from deleting
forceRenderOnLocaleChange
in this PR?
Nothing, I'll happily do it.
If someone rely on the forceRenderOnLocaleChange in v3, for transition to v4, should go and find all places where unsafe t (and other from core) macro calls are used and add a useLingui hook. That might be quite a blocking factor for adopting v4.
they should do it anyways, regardless of whether they had forceRenderOnLocaleChange
true or false.
If they (incorrectly) used the t
macro without useLingui
then their app might break in some cases. If we export LinguiContext
then they can copy the I18nProvider
from v3 into their code base. Then they will have the old behavior of translation rendering but enjoy other benefits of v4.
I agree I need to document this better.
Does this make sense? Thanks! 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vonovak can we move forward with this PR and merge it or you're going to address the discussion regarding the forceRenderOnLocaleChange
here?
Will this fix be merged to version v4 for testing soon? |
@arindamganguly it is still in draft but we will merge it into v4 as soon it will be ready |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vonovak thank you!
@andrii-bodnar Could you please advise when the new version with this fix available? |
@siva-I I'm going to release the |
@andrii-bodnar is there a chance you could do it earlier? we are currently have big blocker and I really wanted to test it if this fixes our issue. I really appreciate the efforts. |
@siva-I the v4.0.0-next.3 is available |
@andrii-bodnar Thanks for the quick update. How can i upgrade my lingui package. The version doesn't seems to be on npmjs I am trying this and it is not updating the next version. |
please see here https://www.npmjs.com/package/@lingui/react?activeTab=versions |
Description
fixes #1136
While working on #1426 I noticed the issue reported in #1136. Using a custom key in the I18nProvider results in remounting of the whole app which is not a standard practice in React providers.
If someone needs to do remounting, I would suggest they implement this themselves, but the lingui/react library should not do this out of the box. The PR removes the usage of
key
prop altogether.Breaking changes:
Previously the whole app would re-mount when calling
activate()
orload()
and this will no longer be the case. If someone uses translations in their components using justthen those occurrences will not re-render. This, I believe, is correct behavior. We need to document how to make those places re-render -
I'm not really sure myselfusing the useLingui hook .In version 2 you could do
Thanks for reviewing! 🙂
Types of changes
Fixes # (issue)
Checklist