Skip to content
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

Question about removing DateFormat and NumberFormat in v3 #627

Closed
pavelkuznetsov opened this issue Apr 6, 2020 · 10 comments
Closed

Question about removing DateFormat and NumberFormat in v3 #627

pavelkuznetsov opened this issue Apr 6, 2020 · 10 comments

Comments

@pavelkuznetsov
Copy link

Hello. Thanks for excellent work with lingui!

I am using NumberFormat and DateFormat from @lingui/react in my project a lot. Today i couldnt find them in the docs, but in section Migration guide from 2.x to 3.x i found --> NumberFormat and DateFormat components were removed. Use date and number formats from @lingui/core package instead.

I'm just wondering is there any specific reason for it? Will it be safe to implement similar wrappers by myself in v3 or are there any concerns about it? (I see that withI18n high-order component was removed as well, but it looks like useLingui can be used instead).

@tricoder42
Copy link
Contributor

Hey @pavelkuznetsov, those components really haven't done anything else than wrapped i18n.date and i18n.number methods. Any reason why you prefer <DateFormat value={date} /> over i18n.date(date)?

@pavelkuznetsov
Copy link
Author

@tricoder42, thanks for quick reply!

I just thought that DateFormat and NumberFormat are the right way to do this kind of formatting in react app, I think that is the only reason I prefered them in the past :) .

But, if I understand correctly, react components (DateFormat and NumberFormat) were decorated with withI18n, so they rerendered when the active language changed. How will this work with the methods?
Here is simple example what i mean - https://codesandbox.io/s/lingui-date-format-example-1t3hn . When we click the button, active language changes, DateFormat receives this data, rerenders and we see new date formatting for selected language.
I dont understand right now how this example should work with the methods. I tried to use imperative api for I18nProvider - i18n instead of language, i18n.activate for language changing and i18n.date(date) for formatting - https://codesandbox.io/s/lingui-date-format-example-o15c8 . Formatting doesnt change if we click the button. Maybe I just dont get it right now, sorry if my question is stupid :)

@tricoder42
Copy link
Contributor

tricoder42 commented Apr 6, 2020

Yeah, you need to pull i18n object from useLingui hook if you want to re-render on locale change. In your example, you need another component with useLingui inside:

function App() {
  const { i18n } = useLingui()

  return (
    <React.Fragment>
        <button
          style={{ marginRight: "30px" }}
          onClick={() => {
            const newLocale = i18n.locale === "en" ? "de" : "en";
            i18n.activate(newLocale);
          }}
        >
          Change locale
        </button>
        {i18n.date(date)}
      </React.Fragment>
  )
}

btw. I assume you use Lingui v3 (from next tag)

You're right that DateFormat and NumberFormat triggered re-render by itself, while useLingui will trigger re-render of the whole component. I don't think it's a bit deal, because when you change locale you usually want to re-render everything from scratch (doesn't happen very often in user workflow), but we can revisit this issue anytime.

@BertrandBordage
Copy link

Is there any equivalent now to these version 2 syntaxes? I couldn’t find either in the docs or by trying plausible syntaxes.

<NumberFormat
  value={value}
  format={{ maximumFractionDigits: 0 }}
/>
<DateFormat
  value={value}
  format={{
    year: 'numeric', month: 'numeric', day: 'numeric',
    hour: 'numeric', minute: 'numeric',
  }}
/>

@talhatahir
Copy link

@BertrandBordage i am looking for something similar to this as well, the document of Lingui only handles the simpler case : i18n.date(value) my code repo contains formatting for some special dates.

@talhatahir
Copy link

Found this @BertrandBordage #299

@BertrandBordage
Copy link

@talhatahir Thanks for sharing!
For now I settled on using this:

Intl.NumberFormat(
  i18n.locale, { maximumFractionDigits: 0 },
).format(value)

@semoal
Copy link
Contributor

semoal commented Feb 11, 2021

@talhatahir Thanks for sharing!
For now I settled on using this:

Intl.NumberFormat(
  i18n.locale, { maximumFractionDigits: 0 },
).format(value)

Why? You can perfectly use number() macro, or date() macro.
If you need some references about how v3 changed from v2, you just need to go https://github.com/lingui/codemods/blob/main/transforms/v2-to-v3.ts, and see all the changes we did

@BertrandBordage
Copy link

@semoal Thanks for insisting on it, I now see that we can use:

i18n.number(value, { maximumFractionDigits: 0 })

I was initially trying to use import { number } from '@lingui/core' or import { number } from '@lingui/react' but it was throwing TypeError: Object(...) is not a function when I was running number(value, { maximumFractionDigits: 0 }).
I would classify this as a documentation issue since date and number are often used in the documentation without specifying where they are coming from, and there is no example of format being passed to it.

@semoal
Copy link
Contributor

semoal commented Feb 11, 2021

Yes, we have tons of pending work inside documentation because v3 has been an amazing rework internally of how Lingui works. Tomas and me pushed hard to release the v3, but documentation it's a bit "old".

The codemod is really helpful and probably will migrate 90/95% of the codebase to lingui v3 best practices. So if you have any doubt the codemod will resolve your question

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants