简体   繁体   English

React-Intl 如何在输入占位符中使用 FormattedMessage

[英]React-Intl How to use FormattedMessage in input placeholder

I'm unsure how to get the values from我不确定如何从中获取值

<FormattedMessage {...messages.placeholderIntlText} />

into a placeholder format like input:转换为占位符格式,例如输入:

<input placeholder={<FormattedMessage {...messages.placeholderIntlText} />} />

as it would return [Object object] in the actual placeholder.因为它会在实际占位符中返回 [Object object]。 Is there a way to get the actual correct value?有没有办法获得实际的正确值?

The <Formatted... /> React components in react-intl are meant to be used in rendering scenarios and are not meant to be used in placeholders, alternate text, etc. They render HTML, not plain text, which is not useful in your scenario. react-intl中的<Formatted... /> React 组件旨在用于渲染场景,而不是用于占位符、替代文本等。它们呈现 HTML,而不是纯文本,这在你的场景。

Instead, react-intl provides a lower level API for exactly this same reason.相反,出于同样的原因, react-intl提供了一个较低级别的 API The rendering components themselves use this API under the hoods to format the values into HTML.渲染组件本身在幕后使用此 API 将值格式化为 HTML。 Your scenario probably requires you to use the lower level formatMessage(...) API.您的场景可能需要您使用较低级别的formatMessage(...) API。

You should inject the intl object into your component by using the injectIntl HOC and then just format the message through the API.您应该使用injectIntl HOC 将intl对象注入到您的组件中,然后通过 API 格式化消息。

Example:示例:

import React from 'react';
import { injectIntl, intlShape } from 'react-intl';

const ChildComponent = ({ intl }) => {
  const placeholder = intl.formatMessage({id: 'messageId'});
  return(
     <input placeholder={placeholder} />
  );
}

ChildComponent.propTypes = {
  intl: intlShape.isRequired
}

export default injectIntl(ChildComponent);

Please note that I'm using some ES6 features here, so adapt according to your setup.请注意,我在这里使用了一些 ES6 功能,因此请根据您的设置进行调整。

  • You can use intl prop from injectIntl HoC您可以使用来自injectIntl HoC 的intl prop
  • You can also provide function as child component:您还可以提供功能作为子组件:
<FormattedMessage {...messages.placeholderIntlText}>
  {(msg) => (<input placeholder={msg} />)}
</FormattedMessage>

For Input placeholder for moredetails对于输入占位符了解更多详情

   <FormattedMessage id="yourid" defaultMessage="search">
    {placeholder=>  
        <Input placeholder={placeholder}/>
        }
    </FormattedMessage>

It's july 2019 and react-intl 3 beta is shipped with a useIntl hook to make these kind of translations easier:现在是 2019 年 7 月,react-intl 3 beta 附带了一个useIntl钩子,以使这些类型的翻译更容易:

import React from 'react';
import {useIntl, FormattedDate} from 'react-intl';

const FunctionComponent: React.FC<{date: number | Date}> = ({date}) => {
  const intl = useIntl();
  return (
    <span title={intl.formatDate(date)}>
      <FormattedDate value={date} />
    </span>
  );
};

export default FunctionComponent;

And then you can make custom hooks to use the methods provided by the API:然后你可以制作自定义钩子来使用 API 提供的方法:

import { useIntl } from 'react-intl'

export function useFormatMessage(messageId) {
  return useIntl().formatMessage({ id: messageId })
}

As from React version >= 16.8, you can use useIntl hook :从 React 版本 >= 16.8 开始,您可以使用useIntl hook

import React from 'react';
import { IntlProvider, useIntl } from 'react-intl';

const FunctionComponent = () => {
    const intl = useIntl();
    const lang = "en";
    const messages = {
      en: {
        'placeholderMessageId': 'placeholder in english',
      },
      fr: {
        'placeholderMessageId': 'placeholder en fançais',
      }
    }
    return ( 
      <IntlProvider locale = {lang} messages = { messages[lang] } >
          <input placeholder = { intl.formatMessage({ id: 'placeholderMessageId' })}/> 
      </IntlProvider >
      );
    };

export default FunctionComponent;

Based on the react intl wiki the implementation of an input box with translatable placeholder will look like:基于react intl wiki ,带有可翻译占位符的输入框的实现如下所示:

import React from 'react';
import { injectIntl, intlShape, defineMessages } from 'react-intl';

const messages = defineMessages({
  placeholder: {
    id: 'myPlaceholderText',
    defaultMessage: '{text} and static text',
  },
});

const ComponentWithInput = ({ intl, placeholderText }) => {
  return (
    <input
      placeholder={ intl.formatMessage(messages.placeholder, { text: placeholderText }) }
    />
  );
};

ComponentWithInput.propTypes = {
  intl: intlShape.isRequired
};

export default injectIntl(ComponentWithInput);

and the useage of it:以及它的用途:

import ComponentWithInput from './component-with-input';
...
render() {
  <ComponentWithInput placeholderText="foo" />
}
...

The id: 'myPlaceholderText', part is necessary to enable the babel-plugin-react-intl to collect the messages for translation. id: 'myPlaceholderText',部分是启用babel-plugin-react-intl收集翻译消息所必需的。

I would like to suggest this solution:我想建议这个解决方案:

import { useIntl } from "react-intl";

export default function MyComponent() {
  const intl = useIntl();

  return (
    <input placeholder={intl.formatMessage({ id: "messageId" })} />
  );
}

You are trying to render a React component named FormattedMessage into a placeholder tag which is expecting a string.您正在尝试将名为 FormattedMessage 的 React 组件渲染到需要字符串的占位符标记中。

You should instead just create a function named FormattedMessage that returns a string into the placeholder.您应该改为创建一个名为 FormattedMessage 的函数,该函数将字符串返回到占位符中。

function FormattedMessage(props) {
    ...
}

<input placeholder=`{$(FormattedMessage({...messages.placeholderIntlText})}` />

Consider this possibility.考虑这种可能性。

The simplest solution最简单的解决方案

<IntlMessages id="category.name">
    {text => (
        <Input placeholder={text} />
    )}
</IntlMessages>

OR

在此处输入图片说明

In my case I had the whole app in one file, so using export wouldn't work.在我的情况下,我将整个应用程序放在一个文件中,因此使用export不起作用。 This one uses the normal class structure so you can use the state and other functionality of React if needed.这个使用普通的类结构,因此您可以在需要时使用 React 的状态和其他功能。

class nameInputOrig extends React.Component {
  render () {
    const {formatMessage} = this.props.intl;
    return (
        <input type="text" placeholder={formatMessage({id:"placeholderIntlText"})} />
    );
  }
}

const nameInput = injectIntl(nameInputOrig);

Apply using the created constant:使用创建的常量应用:

class App extends React.Component {
    render () {
        <nameInput />
    }
}

Starting from the @gazdagerg 's answer, I have adapted his code in order to:从@gazdagerg 的回答开始,我修改了他的代码以便:

  • having a new component that is a wrapper over an input有一个新组件,它是输入的包装器
  • receives an ID of a string from locale conf从语言环境 conf 接收字符串的 ID
  • based on the ID, it returns the string in respect to the global locale setting根据 ID,它返回与全局语言环境设置相关的字符串
  • handling the situation when the string ID is not set (this caused exception and page to crash)处理没有设置字符串ID的情况(这会导致异常和页面崩溃)

    import React from 'react';
    import { injectIntl, intlShape, defineMessages } from 'react-intl';


    const InputWithPlaceholder = ({ intl, placeholder }) => {

      const messages = defineMessages({
        placeholder: {
          id: placeholder,
          defaultMessage: '',
        },
      });

      if(messages.placeholder.id) {
        return (
          <input placeholder={ intl.formatMessage(messages.placeholder) } />
        );
      } else {
        return (
          <input/>
        );
      }
    };

    InputWithPlaceholder.propTypes = {
      intl: intlShape.isRequired
    };

    export default injectIntl(InputWithPlaceholder);

You can use it in other file by:您可以通过以下方式在其他文件中使用它:

  1. import the new component导入新组件
  2. use it with the ID of the locale string as parameter将它与语言环境字符串的 ID 作为参数一起使用
import InputWithIntlPlaceholder from 'your/path/to/component/InputWithIntlPlaceholder';

... more code here ...

<InputWithIntlPlaceholder placeholder="your.locale.string.id" />

Like this:像这样:

import React, {PropTypes} from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
 
/**
* {
* "hello": "Hello",
* "world": "World"
* }
*/
 
// pure function
const PureFunciton = injectIntl(({ intl }) => {
return (
  <div>
    <p>{intl.formatMessage({ id: 'hello' })}</p>
    <p><FormattedMessage id="world" /></p>
  </div>
)
});
 
// class Component
class componentName extends Component {
  handleStr = () => {
    // return 'Hello';
    const { intl } = this.props;
    return intl.formatMessage({ id: 'hello' })
  }
  render() {
    return (
      <div>
        <p>{this.handleStr()}</p>
        <p><FormattedMessage id="world" /></p>
      </div>
    );
  }
}
 
export default injectIntl(connect(componentName));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM