Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-intl, use api with Typescript

I would like to use the formatMessage function of the react-intl API to insert a message as placeholder, but I can't figure out the right way to access this function.

Here is a simplified version of what I have:

// index.tsx
<IntlProvider locale={`fr-FR`} messages={messages_fr}>
    <NameForm/>
</IntlProvider>
// nameForm.tsx
interface NameFormProps {
    intl?: InjectedIntlProps,
}

export default injectIntl(NameForm);

class NameForm extends React.Component<NameFormProps, {}> {
    render() {
        let namePlaceholder = this.props.intl.formatMessage({
            id: "NAME_PLACEHOLDER",
            defaultMessage: "name"
        });
        
        return (
            <form>
                <input placeholder={namePlaceholder} type="text"/>
            </form>
        );
    }
}

I used InjectedIntlProps as type of the intl prop, because IntlShape didn't seem to provide a formatMessage method.

I Added a ? to the intl prop because I kept having a Property 'intl' is missing (but isn't injectIntl supposed to return a component without this prop?)

Now it compiles, but when running I get an error Cannot read property 'displayName' of undefined. I guess it's because the default export doesn't have an explicit name).

I feel I'm not going in the right direction, but can't find any example of a typescript/react-intl project.

Thanks for your help!

like image 788
Emarco Avatar asked Nov 24 '16 11:11

Emarco


1 Answers

Updated:

After reading the docs about upgrade to 3.x, I found it has a simpler way, just use useIntl hook:

Sample code:

import { FormattedMessage, useIntl } from 'react-intl'


type Props = {
  placeholder: string,
}

function MyComponent({ placeholder }: Props) {
  const intl = useIntl()

  return (
    <input placeholder={intl.formateMessage({id: placeholder})} type="text"/>
  )
}

export default MyComponent

Old:

In the react-intl new version (3.12.0), we don't need @types/react-intl anymore, react-intl has its own type definition, and InjectedIntlProps doesn't exist anymore, it is named WrappedComponentProps instead.

My sample code:

import { FormattedMessage, injectIntl, WrappedComponentProps } from 'react-intl'

type Props = {
  placeholder: string,
} & WrappedComponentProps

function MyComponent({ placeholder, intl }: Props) {

  return (
    <input placeholder={intl.formateMessage({id: placeholder})} type="text"/>
  )
}

export default injectIntl(MyComponent)
like image 101
Spark.Bao Avatar answered Sep 20 '22 11:09

Spark.Bao