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 seems to offer 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 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 !
While working with the same problem, I found that neither including InjectedIntlProps
as a member, as mentioned in the question, nor extending from it, as mentioned in another answer, satisfies the type checker. When extending from InjectedIntlProps
, the call to injectIntl
checked, but using the resulting component in JSX expected me to provide an intl
property. The following strategy resolved this though:
interface NameFormProps {
// Include all custom properties here.
}
class NameForm extends React.Component<NameFormProps & InjectedIntlProps, {}> {
// Class body.
}
export default injectIntl(NameForm);
The problem was due to the version of the typescript definition. When using @types/react-intl": "^2.2.0", it works like a charm.
(edit) Few changes needed to make it work :
//index.tsx
<IntlProvider locale={`fr-FR`} messages={messages_fr}>
<NameForm/>
</IntlProvider>,
//nameForm.tsx
interface NameFormProps extends InjectedIntlProps {
placeholder: string,
}
class NameForm extends React.Component<NameFormProps, {}> {
render() {
let namePlaceholder = this.props.intl.formatMessage({
id: this.props.placeholder,
defaultMessage: "name"
});
return (
<form>
<input placeholder={namePlaceholder} type="text"/>
</form>
);
}
export default injectIntl(NameForm);
Neither of the existing solutions worked for me. Instead it was due to injectIntl
inferring the properties to include InjectedIntlProps
.
To fix it, I had to explicitly tell injectIntl
what props the wrapped component should have:
interface NameFormProps {
}
class NameForm extends React.Component<NameFormProps & InjectedIntlProps> {
}
export default injectIntl<NameFormProps>(NameForm);
If there are no props, it needs to be changed slightly:
class NameForm extends React.Component<InjectedIntlProps> {
}
export default injectIntl<{}>(NameForm);
来源:https://stackoverflow.com/questions/40784817/react-intl-use-api-with-typescript