-
Notifications
You must be signed in to change notification settings - Fork 393
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
feat: memoizable react translations #1721
feat: memoizable react translations #1721
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
size-limit report 📦
|
Codecov ReportPatch and project coverage have no change.
Additional details and impacted files@@ Coverage Diff @@
## main #1721 +/- ##
=======================================
Coverage 75.87% 75.87%
=======================================
Files 80 80
Lines 2052 2052
Branches 526 526
=======================================
Hits 1557 1557
Misses 382 382
Partials 113 113
☔ View full report in Codecov by Sentry. |
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.
Exactly what we need ❤️
By the way, i also thought about making something like that as default solution in docs instead of using global import { t } from "@lingui/macro";
// ❌ Bad because there no direct relation between `t` and `useLingui`
export const WelcomeMsg = React.memo(() => {
useLingui();
return <Text>greeting: {t`Welcome`}</Text>;
}); import { t } from "@lingui/macro";
// ❌ Better than first one, but still bad because too verbose,
// and Developers can omit `(i18n)` part and don't get consequences immediately
export const WelcomeMsg = React.memo(() => {
const { i18n } = useLingui();
return <Text>greeting: {t(i18n)`Welcome`}</Text>;
}); So I thought about implementing a new macro import { useLingui } from "@lingui/macro";
// ✅ Good, as you see direct dependecy on the hook,
// but really hard to implement from Transpilation point of view
export const WelcomeMsg = React.memo(() => {
const { t } = useLingui();
return <Text>greeting: {t`Welcome`}</Text>;
}); But thought about that once again and i also came to similar to yours solution, that instead of creating new complicated macro we can achieve the same result with existing code. We only need to change documentation to encourage people to use different methods: import { useLingui } from "@lingui/macro";
export const WelcomeMsg = React.memo(() => {
const { i18n } = useLingui();
// expand macro and mark message for extraction with `msg`
return <Text>greeting: {i18n.t(msg`Welcome`)}</Text>;
}); Despite the fact, we came to here solving diffrent issues, we end up with a similar solution. |
@thekip so just to make sure I understand :) (I changed the examples to use import { msg } from "@lingui/macro";
export const WelcomeMsg = () => {
const { _ } = useLingui();
return <Button title={_(msg`Do something`)} />
} or in case someone needs to use memo: import { msg } from "@lingui/macro";
export const WelcomeMsg = () => {
const { _ } = useLingui();
const memoizedTitle = useMemo(() => {
return _(msg`Do something`);
}, [_]);
return <Button title={memoizedTitle} />
} I really like this one that you suggested, thought about it as well, but I don't think I have the bandwidth to explore the transpilation :/ import { useLingui } from "@lingui/macro"; // or "@lingui/react"?
// ✅ Good, as you see direct dependency on the hook,
// but really hard to implement from Transpilation point of view
export const WelcomeMsg = () => {
const { t } = useLingui();
return <Button title={t`Do something`} />
} which would transpile to this? import { useLingui } from "@lingui/react";
export const WelcomeMsg = () => {
const { t } = useLingui();
return (
<Button
title={t(
/*i18n*/ {
id: "some_hash",
message: "Do something",
},
)}
/>
);
}; maybe we can keep the docs as they are and point out to this possible improvement, maybe someone will contribute it 😄 |
@vonovak yes, exactly. Regarding new macro: import { useLingui } from "@lingui/macro"; // or "@lingui/react"?
export const WelcomeMsg = () => {
const { t } = useLingui();
return <Button title={t`Do something`} />
} This ideally should be transpiled to something like import { useLingui } from "@lingui/macro"; // or "@lingui/react"?
export const WelcomeMsg = () => {
const { i18n } = useLingui();
return <Button title={i18n._(`<expanded macro>`)} />
} So to achieve this we need to find all usages of So i prefer may be less elegant but more future-proof solution. |
I believe the transpilation result you gave would be more complicated than needed because it transforms import { useLingui } from "@lingui/macro"; // or "@lingui/react"?
export const WelcomeMsg = () => {
const { t } = useLingui();
const greeting = useMemo(() => {
return t`hello world`
}, [t]);
return <Button title={greeting} />
} Anyhow, let me wrap this up, I'll add the docs for what I added here and then mark as ready for review :) |
@andrii-bodnar can you please review / merge? I have some other stuff in the pipeline and would like to get this merged first, thanks :) edit: I see you're on vacation, hope you enjoyed it! :) |
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!
Sorry for the late response 🙏
Description
this is an improvement for #1690 (#1690 (comment)), addresses difficulty with the current api: https://lingui.dev/tutorials/react-patterns#memoization-pitfall
I'm opening this for feedback; after potential issues are addresses, I can write docs.
This allows the following construct to work correctly:
It feels like there are a lot of ways to achieve more or less the same thing now, with
t
macro,Trans
,msg
... I think it's okay to add this, if there are quality docs.Types of changes
Fixes # (issue)
Checklist