【问题标题】:React-intl, use api with TypescriptReact-intl,使用 api 和 Typescript
【发布时间】:2017-04-08 15:56:15
【问题描述】:

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

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

// 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 作为intl 属性的类型,因为IntlShape 似乎没有提供formatMessage 方法。

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

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

我觉得我的方向不对,但找不到 typescript/react-intl 项目的任何示例。

感谢您的帮助!

【问题讨论】:

    标签: typescript react-intl


    【解决方案1】:

    问题是由于打字稿定义的版本造成的。 当使用@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);
    

    【讨论】:

    • 对我不起作用...但是将“扩展 React.Component”更改为“扩展 React.PureComponent”可以。
    • 对我来说也很重要...“导出默认值”必须在被导出的类之后!
    • 我又编辑了一遍。确实,你需要将导出行放在文件末尾,你可以扩展“InjectedIntlProps”而不是手动添加 intl props
    【解决方案2】:

    在处理同样的问题时,我发现既不包括 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);
    

    【讨论】:

      【解决方案3】:

      现有的解决方案都不适合我。相反,这是由于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);
      

      【讨论】:

        【解决方案4】:

        更新:

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

        示例代码:

        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 不再存在,它被命名为@987654326 @ 代替。

        我的示例代码:

        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)
        

        【讨论】:

          【解决方案5】:

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

          import { WrappedComponentProps } from 'react-intl';
            
          interface IProps extends WrappedComponentProps {
            // other props
          }
          

          【讨论】:

            猜你喜欢
            • 2019-07-29
            • 2017-12-25
            • 2018-06-10
            • 2020-05-12
            • 1970-01-01
            • 2021-04-25
            • 2017-10-30
            • 1970-01-01
            • 2017-02-11
            相关资源
            最近更新 更多