13

我想formatMessage使用react-intl来插入一条消息作为占位符,但我不知道访问此功能的正确方法。

这是我所拥有的简化版本:

// 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>
        );
    }
}

我用作道具InjectedIntlProps的类型,因为似乎没有提供方法。intlIntlShapeformatMessage

我添加了一个?到intl道具,因为我一直有一个Property 'intl' is missing(但不injectIntl应该在没有这个道具的情况下返回一个组件?)

现在它编译了,但是运行时出现错误Cannot read property 'displayName' of undefined。我猜这是因为默认导出没有明确的名称)。

我觉得我没有朝着正确的方向前进,但是找不到 typescript/react-intl 项目的任何示例。

谢谢你的帮助!

4

5 回答 5

14

在处理同样的问题时,我发现既不包括InjectedIntlProps问题中提到的成员,也不像另一个答案中提到的那样从成员中扩展,都满足类型检查器的要求。从 扩展时InjectedIntlProps,对检查的调用injectIntl,但在 JSX 中使用生成的组件希望我提供一个intl属性。但是,以下策略解决了这个问题:

    interface NameFormProps {
        // Include all custom properties here.
    }

    class NameForm extends React.Component<NameFormProps & InjectedIntlProps, {}> {
        // Class body.
    }

    export default injectIntl(NameForm);
于 2017-11-08T10:24:03.767 回答
9

问题是由于打字稿定义的版本造成的。当使用 @types/react-intl": "^2.2.0" 时,它就像一个魅力。

(编辑)使其工作所需的少量更改:

//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);
于 2017-01-04T12:53:05.563 回答
8

更新:

在阅读了关于升级到 3.x的文档后,我发现它有一个更简单的方法,只需使用useIntl钩子:

示例代码:

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

老的:

在 react-intl 新版本(3.12.0)中,我们不再需要@types/react-intl了,react-intl 有自己的类型定义,InjectedIntlProps不再存在,WrappedComponentProps取而代之的是命名。

我的示例代码:

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)
于 2020-02-12T09:48:06.547 回答
6

现有的解决方案都不适合我。相反,这是由于injectIntl推断要包含的属性InjectedIntlProps

为了解决这个问题,我必须明确告诉injectIntl包装组件应该有哪些道具:

interface NameFormProps {
}

class NameForm extends React.Component<NameFormProps & InjectedIntlProps> {
}

export default injectIntl<NameFormProps>(NameForm);

如果没有props,需要稍微改动一下:

class NameForm extends React.Component<InjectedIntlProps> {
}

export default injectIntl<{}>(NameForm);
于 2018-03-10T12:31:43.380 回答
1

对于那些现在来到这个线程的人来说InjectedIntlProps,当前版本不再支持 type react-intl。而是使用WrappedComponentProps

IE

import { WrappedComponentProps } from 'react-intl';
  
interface IProps extends WrappedComponentProps {
  // other props
}
于 2021-07-14T12:45:52.303 回答