Как получить строку в ReactIntl ​​2.0 без использования FormattedMessage

Пожалуйста, поправьте меня, если я ошибаюсь, FormattedMessage в ReactIntl ​​возвращает строку, обернутую тегами span. В ReactIntl ​​1.2 у нас есть возможность использовать this.getIntlMessage('key') для получения только строковой части.

Вот мой вопрос: есть ли аналог в ReactIntl ​​2.0? Я знаю, что строку можно получить, используя шаблон Function-As-Child в FormattedMessage как

<FormattedMessage id="placeholder">
    {(formattedValue)=>(
        <MyComponent ref="mycomponent" placeholder={formattedValue}/>
    )}
</FormattedMessage>

Однако это портит «ссылку» в моем компоненте, и я больше не могу получить доступ к компоненту, используя this.refs.mycomponent.


person C.Lee    schedule 03.02.2016    source источник


Ответы (5)


Есть лучшее решение placeholder проблемы.

<FormattedMessage ...messages.placeholderIntlText>
  {
     (msg) =>  <input type="text" placeholder = {msg} />
  }
</FormattedMessage>
person Jacky Hu    schedule 29.06.2017

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

именно так вы гораздо проще используете объект intl внутри класса реагирования.

примечание: компонент рендеринга (основной компонент) должен быть заключен в IntlProvider.

class MySubComponent extends React.Component{
  {/*....*/}

  render(){
    return(
     <div>
        <input type="text" placeholder = {this.context.intl.formatMessage({id:"your_id", defaultMessage: "your default message"})}
     </div>

    )
  }
   }
MySubComponent.contextTypes ={
 intl:React.PropTypes.object.isRequired
}

Определив contextTypes, вы сможете использовать объект intl, который является реквизитом типа контекста. См. контекст реакции для более подробной информации.

person Kinsly Roberts    schedule 26.08.2016

Хорошо, для этого есть обходной путь. Я могу добавить ReactIntl в качестве контекста в компонент следующим образом:

contextTypes: {
    intl: React.PropTypes.object.isRequired,
},

Затем при попытке получить строку сообщения и использовать ее, например, в заполнителе, я могу сделать это.

<MyComponent ref="mycomponent" placeholder={this.context.intl.messages.placeholder}/>
person C.Lee    schedule 03.02.2016
comment
ответ на самом деле не очень информативный, рассмотрите возможность добавления дополнительной информации - person Christopher Thomas; 31.03.2016

Если вы используете функциональный компонент, вы можете использовать хук useIntl(), чтобы получить объект intl и получить сообщение как string из приведенного ниже фрагмента кода.

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

export function MyFunctionalComponent() {
    const intl = useIntl();
    return (
        <div>
            <p>{intl.formatMessage({id: "MyKey"})}</p>
        </div>
    )
}

Примечание. Родительский компонент должен быть обернут вокруг </IntlProvider> провайдера.

person Burhanuddin Rashid    schedule 23.02.2021

Я решил эту проблему, используя React render props.

Я создал пакет npm, который его реализует: http://g14n.info/react-intl-inject/

Это такой компонент

import { injectIntl } from 'react-intl'

export default function reactIntlInject ({ children, ...props }) {
  if (typeof children === 'function') {
    return (
      children(props)
    )
  } else {
    return null
  }
}

И вы можете использовать его, чтобы обернуть компоненты, которые, например, имеют свойства, которые вы хотите перевести, например.

import React, { Component } from 'react'
// Import the package I created, available on npm with MIT license....
import InjectIntl from 'react-intl-inject'
// ...or copy the code above in a file in your project and import it, somethong like
// import InjectIntl from './path/to/my/render/prop/component'

class MyComponent extends Component {
  render () {
    return (
      <InjectIntl>
        {({ intl }) => (
          <button
            type='submit'
            value={intl.formatMessage({ id: 'enter.submit' })}
          />
        )}
      </InjectIntl>
    )
  }
}

export default injectIntl(reactIntlInject)
person Gianluca Casati    schedule 31.03.2019