React-intl,使用 api 和 Typescript
Posted
技术标签:
【中文标题】React-intl,使用 api 和 Typescript【英文标题】:React-intl, use api with 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 项目的任何示例。
感谢您的帮助!
【问题讨论】:
【参考方案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
【讨论】:
以上是关于React-intl,使用 api 和 Typescript的主要内容,如果未能解决你的问题,请参考以下文章
使用 React-intl 的 Redux-form 字段级验证和错误翻译