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