C.Lee
C.Lee

Reputation: 11249

How to retrieve a string in ReactIntl 2.0 without using FormattedMessage

Please correct me if I am wrong, FormattedMessage in ReactIntl returns a string wrapped by span tags. In ReactIntl 1.2, we have the option to use this.getIntlMessage('key') to get only the string part.

Here is my question: Is there an equivalent of that in ReactIntl 2.0? I am aware that the string can be obtained by using the Function-As-Child pattern in FormattedMessage as

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

However, it messes up the 'ref' in my component and I can't access to the component using this.refs.mycomponent any more.

Upvotes: 15

Views: 17989

Answers (6)

Joakim
Joakim

Reputation: 521

This is what I end up with. I added a central help function that retrieves the plain text.

import { useIntl } from 'react-intl';

export const GetTranslateText = (textId) => {
  const intl = useIntl();
  const plainText = intl.formatMessage({ id: textId });

  return plainText;
};

Then it works fine to use to just retrieve the text in code or component

import { GetTranslateText } from '/utils/IntlHelpers';
.
.
 <input type="text" placeholder={GetTranslateText('your.text.id')} /> 
.
.

Upvotes: 0

Burhanuddin Rashid
Burhanuddin Rashid

Reputation: 5370

If you are using a functional component, then you can use useIntl() hook to get intl object and get the message as string from below code snippet.

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

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

Note: You Parent component should be wrapped around </IntlProvider> provider.

Upvotes: 2

Gianluca Casati
Gianluca Casati

Reputation: 3753

I solved this problem using React render props.

I created an npm package that implements it: http://g14n.info/react-intl-inject/

It is a component like this

import { injectIntl } from 'react-intl'

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

And you can use it to wrap the components that for example has props you want to translate, for example

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)

Upvotes: 0

Jacky Hu
Jacky Hu

Reputation: 146

There is a better to solve placeholder problem.

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

Upvotes: 13

Kinsly Roberts
Kinsly Roberts

Reputation: 131

You can easily return string using intl object provided by react-intl.

this is how you use intl object inside react class in much more easier way.

note: Render Component (main component) should wrap with 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
}

By defining contextTypes it will enable you to use intl object which is a context type prop. See react context for more details.

Upvotes: 9

C.Lee
C.Lee

Reputation: 11249

Ok, there is a work around for that. I can add ReactIntl as the context in the component like this:

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

Then when trying to retrieve the string of the message and use it, for example in a placeholder, I can do this.

<MyComponent ref="mycomponent" placeholder={this.context.intl.messages.placeholder}/>

Upvotes: 5

Related Questions