5

So my index.js has something like this:

import trFi from './translations/fi_FI.json';
import trSv from './translations/sv_SE.json';

ReactDOM.render(
  <IntlProvider
    locale={my_locale}
    messages={{ fi: trFi, sv: trSv }[my_locale]}
  >
      <Root />
  </IntlProvider>
);

And Root has multiple sub components and all. Now how can I get the provided locale and messages in these sub components? I know I can pass them as props to Root, which again passes them down, but my tree is rather deep and it's a pain in the ass to maintain this.

Is it possible to access this locale and messages passed to IntlProvider in the subcomponents directly?

Markus Meskanen
  • 19,939
  • 18
  • 80
  • 119

3 Answers3

6

As explained in the docs here, you can use a HOC (High Order Component) to wrap your components where they need to access internationalized data provided by <IntlProvider /> at the root of your component tree.

Also, you have to use the <Formatted*> components to actually use that data for display.

Here's an example from the docs above:

import React from 'react';
import { injectIntl, FormattedRelative } from 'react-intl';

const PostDate = ({ date, intl }) => (
    <span title={ intl.formatDate(date) }>
        <FormattedRelative value={ date }/>
    </span>
);

PostDate.propTypes = {
    date: PropTypes.any.isRequired,
    intl: intlShape.isRequired,
};

export default injectIntl(PostDate);

In addition to format* helpers, the config props, including messages andlocale can also be accessed directly down the tree via the same component prop intl (see the type definition intlShape here):

const { locale, messages } = this.props.intl;
Pandaiolo
  • 11,165
  • 5
  • 38
  • 70
  • Yeah the first link is what I originally followed through, but this particular use case requires me to translate ``'s `placeholder` attribute, and thus I can't use the `` components for this. – Markus Meskanen Apr 05 '17 at 09:14
  • "The messages themselves can be accessed from the props of your components if you need direct access. This is documented in this example" I don't quite follow here, the example just uses the global `messages` object? I was particularly asking if it's possible to fetch the `message` object passed to `` in sub components, or if my only option is to forward it throught the whole tree as props – Markus Meskanen Apr 05 '17 at 09:15
  • 1
    Wow yeah, I answered way too quickly, sorry! I updated my answer accordingly. – Pandaiolo Apr 05 '17 at 09:57
1

When writing react with hooks you can use the useIntl hook to access the intl object.

import React from 'react'
import {useIntl, FormattedDate} from 'react-intl'

const FunctionComponent: React.FC<{date: number | Date}> = ({date}) => {
  const intl = useIntl()
  return (
    <span title={intl.formatDate(date)}>
      <FormattedDate value={date} />
    </span>
  )
}

export default FunctionComponent

(example taken from, and more info to be found at, https://formatjs.io/docs/react-intl/api/#useintl-hook )

Pieter
  • 17,435
  • 8
  • 50
  • 89
0

Yep, that is possible. Import the useIntl hook like this:

import { useIntl } from 'react-intl'

const MyComponent: = () => {
  const intl = useIntl()
  console.log('What you need is here: ', intl.locale)

  return (
    <>
      ...
    </>
  )
}

export default MyComponent