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

docs: Update react patterns #980

Merged
merged 8 commits into from
Feb 23, 2021
Merged
130 changes: 28 additions & 102 deletions docs/tutorials/react-patterns.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,10 @@ In the following example, message ``Image caption`` will be extracted and used a

.. code-block:: jsx

import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"

export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t`Image caption`)} />
)}
</I18n>
)
return <img src="..." alt={t`Image caption`} />
}

Using custom ID
Expand All @@ -79,45 +72,32 @@ Messages ``msg.header`` and ``msg.hello`` will be extracted with default values
With :jsmacro:`t`
^^^^^^^^^^^^^^^^^

If you're using custom IDs in your project, call :jsmacro:`t` with ID as a first
argument and then use string templates as usual:
If you're using custom IDs in your project, call :jsmacro:`t` with a message descriptor
object and pass ID as ``id`` prop:

.. code-block:: jsx

import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"

export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t('msg.caption')`Image caption`)} />
)}
</I18n>
)
return <img src="..." alt={t({id: 'msg.caption', message: `Image caption`})} />
}

Message ``msg.caption`` will be extracted with default value ``Image caption``.

For all other js macros (:jsmacro:`plural`, :jsmacro:`select`, :jsmacro:`selectOrdinal`),
pass ID as the first param (in this case, ``'msg.caption'``):
use them inside :jsmacro:`t` macro to pass ID (in this case, ``'msg.caption'``).

.. code-block:: jsx

import { I18n } from "@lingui/react"
import { plural } from "@lingui/macro"
import { t, plural } from "@lingui/macro"

export default function ImageWithCaption({ count }) {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(plural('msg.caption', {
value: count,
one: "# image caption",
other: "# image captions",
}))} />
)}
</I18n>
<img src="..." alt={t({id: 'msg.caption', message: plural(count, {
one: "# image caption",
other: "# image captions",
})})} />
)
}

Expand All @@ -131,81 +111,32 @@ attributes:

<img src="..." alt="Image caption" />

In such case you need to use :component:`I18n` render prop component to access ``i18n``
object and :jsmacro:`t` macro to wrap message:

1. Use :js:func:`withI18n` HOC or :component:`I18n` render prop component from ``@lingui/react``, to access
``i18n`` object.

2. Call :js:meth:`i18n._`` to translate message wrapped in JS macros. :jsmacro:`t` is
equivalent for :jsxmacro:`Trans`, :jsmacro:`plural` is equivalent to :component:`Plural`.

.. code-block:: jsx

// using the withI18n HOC
import { withI18n } from "@lingui/react"
import { t } from "@lingui/macro"

function ImageWithCaption({ i18n }) {
return <img src="..." alt={i18n._(t`Image caption`)} />
}

export default withI18n(ImageWithCaption)
In such case you need to use :jsmacro:`t` macro to wrap message. :jsmacro:`t` is
equivalent for :jsxmacro:`Trans`, :jsmacro:`plural` is equivalent to :jsxmacro:`Plural`.

.. code-block:: jsx

// using the render prop
import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"

export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t`Image caption`)} />
)}
</I18n>
)
return <img src="..." alt={t`Image caption`} />
}


Translations outside React components
=====================================

Another common pattern is when you need to access translations (``i18n`` object)
outside React components, for example inside ``redux-saga``:

1. Create your own instance of ``i18n`` using :js:func:`setupI18n` form ``@lingui/core``

2. Pass this instance as ``i18n`` prop to :component:`I18nProvider`.

.. code-block:: jsx

// App.js
import { setupI18n } from "@lingui/core"
import { I18nProvider } from "@lingui/react"

export const i18n = setupI18n()

export default function App() {
return (
<I18nProvider i18n={i18n}>
{/* Our app */}
</I18nProvider>
)
}

3. Whenever you are outside React context (i.e. you can't access props), you can use this
``i18n`` object.
Another common pattern is when you need to access translations outside React components,
for example inside ``redux-saga``. You can use :jsmacro:`t` macro outside React context
as usual:

.. code-block:: jsx

import { i18n } from "./App.js"
import { t } from "@lingui/macro"

export function alert() {
// use i18n as if you were inside a React component
alert(i18n._(t`...`))
// use t as if you were inside a React component
alert(t`...`)
}

Lazy translations
Expand All @@ -232,16 +163,17 @@ passing it to :jsxmacro:`Trans` as its ``id`` prop:
<ul>
{favoriteColors.map(color => (
<li><Trans id={color}/></li>
}
))}
</ul>
)
}

Or to render the message descriptor as a string-only translation, just pass it to
the :js:meth:`I18n._` method as usual:
the :js:meth:`I18n._` method:

.. code-block:: jsx

import { i18n } from '@lingui/core'
import { t } from "@lingui/macro"

const favoriteColors = [
Expand All @@ -251,9 +183,11 @@ the :js:meth:`I18n._` method as usual:
t`Green`,
]

const translatedColorNames = favoriteColors.map(
color => i18n._(color)
)
export function getTranslatedColorNames() {
return favoriteColors.map(
color => i18n._(color)
)
}

Passing messages as props
-------------------------
Expand All @@ -278,22 +212,14 @@ element as the prop:
}

If you need the prop to be displayed as a string-only translation, you can pass
a message descriptor (tagged with the :jsmacro:`t` macro), and have the component
render it as a string using lazy translation:
a message tagged with the :jsmacro:`t` macro:

.. code-block:: jsx

import { t } from "@lingui/macro"
import { I18n } from "@lingui/react"

export default function ImageWithCaption(props) {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(props.caption)} />
)}
</I18n>
)
return <img src="..." alt={props.caption} />
}

export function HappySad(props) {
Expand Down
1 change: 1 addition & 0 deletions docs/tutorials/react.rst
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@ in the documentation for more info and happy internationalizing!
Further reading
===============

- `Common i18n patterns in React <./react-patterns.html>`_
- `@lingui/react reference documentation <../ref/react.html>`_
- `@lingui/cli reference documentation <../ref/cli.html>`_
- `Pluralization Guide <../guides/plurals.html>`_