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

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

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

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

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

как он вернет [Object object] в фактический заполнитель. Есть ли способ получить фактическое правильное значение?

6 ответов


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

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

вы должны впрыснуть 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 здесь, поэтому адаптируйтесь в соответствии с вашей настройкой.


  • можно использовать intl реквизит injectIntl HoC
  • вы также можете предоставить функцию в качестве дочернего компонента:

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


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

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

function FormattedMessage(props) {
    ...
}

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

на основе 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);

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

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

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


в моем случае у меня было все приложение в одном файле, поэтому с помощью 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 />
    }
}

такой:

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