Подтвердить что ты не робот

React-Intl Как использовать FormattedMessage на вкладке ввода

Я не уверен, как получить значения из

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

в формат заполнителя, такой как ввод:

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

поскольку он возвратит [Объект объекта] в фактическом заполнителе. Есть ли способ получить правильное значение?

4b9b3361

Ответ 1

Компоненты <Formatted... /> React в react-intl предназначены для использования в сценариях рендеринга и не предназначены для использования в заполнителях, альтернативном тексте и т.д. Они отображают HTML, а не обычный текст, что не полезно в вашем сценарий.

Вместо этого react-intl предоставляет API нижнего уровня именно по этой же причине. Компоненты рендеринга сами используют этот API под капотами для форматирования значений в HTML. Вероятно, для вашего сценария вам потребуется использовать API уровня ниже formatMessage(...).

Вы должны ввести объект intl в свой компонент, используя injectIntl HOC, а затем просто отформатировать сообщение через API.

Пример:

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

Обратите внимание, что я использую некоторые функции ES6 здесь, поэтому адаптируйте их в соответствии с вашими настройками.

Ответ 2

  • Вы можете использовать intl опору из injectIntl HoC
  • Вы также можете предоставить функцию в качестве дочернего компонента:
<FormattedMessage {...messages.placeholderIntlText}>
  {(msg) => (<input placeholder={msg} />)}
</FormattedMessage>

Ответ 3

Для ввода заполнителя для более подробной информации

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

Ответ 4

На основе реагирует на вики реализация поля ввода с переводимым заполнителем будет выглядеть следующим образом:

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

и его использование:

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

Часть id: 'myPlaceholderText', необходима для того, чтобы babel-plugin-реагировать-intl собирал сообщения для перевода.

Ответ 5

Вы пытаетесь создать компонент React с именем FormattedMessage в тег-заполнителя, который ожидает строку.

Вместо этого вы должны просто создать функцию с именем FormattedMessage, которая возвращает строку в placeholder.

function FormattedMessage(props) {
    ...
}

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

Ответ 6

Это июль 2019 года, и реагирующая бета-версия 3 поставляется с крючком 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;

И тогда вы можете создавать собственные хуки для использования методов, предоставляемых API:

import { useIntl } from 'react-intl'

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

Ответ 7

В моем случае у меня было все приложение в одном файле, поэтому использование export не помогло бы. Это использует обычную структуру классов, поэтому вы можете использовать состояние и другие функциональные возможности React, если это необходимо.

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

const nameInput = injectIntl(nameInputOrig);

Применить с помощью созданной константы:

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

Ответ 8

Начиная с ответа @gazdagerg, я адаптировал его код для того, чтобы:

  • имея новый компонент, который является оберткой над входом
  • получает идентификатор строки из языкового стандарта conf
  • на основе идентификатора возвращает строку в соответствии с настройкой глобальной локали
  • обработка ситуации, когда идентификатор строки не задан (это вызвало исключение и сбой страницы)

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

Вы можете использовать его в другом файле:

  1. импортировать новый компонент
  2. используйте его с идентификатором строки локали в качестве параметра
import InputWithIntlPlaceholder from 'your/path/to/component/InputWithIntlPlaceholder';

... more code here ...

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

Ответ 9

Вот так:

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