web-dev-qa-db-fra.com

React-Intl Comment utiliser FormattedMessage dans un espace réservé d'entrée

Je ne sais pas comment obtenir les valeurs de 

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

dans un format d'espace réservé comme entrée:

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

comme il retournerait [Object object] dans l'espace réservé actuel. Existe-t-il un moyen d'obtenir la valeur correcte exacte?

35
Bryan

Les composants <Formatted... /> React dans react-intl sont destinés à être utilisés dans les scénarios de rendu et ne sont pas destinés à être utilisés dans des espaces réservés, du texte alternatif, etc.

react-intl fournit plutôt un niveau inférieur API pour exactement la même raison. Les composants de rendu utilisent eux-mêmes cette API pour mettre en forme les valeurs en HTML. Votre scénario nécessite probablement que vous utilisiez l'API formatMessage(...) de niveau inférieur.

Vous devez injecter l'objet intl dans votre composant en utilisant le HOC injectIntl, puis formater simplement le message via l'API.

Exemple:

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

Veuillez noter que j'utilise certaines fonctionnalités de l'ES6 ici. Adaptez-vous donc à votre configuration.

68
lsoliveira
  • Vous pouvez utiliser intl prop de injectIntl HoC
  • Vous pouvez également fournir une fonction en tant que composant enfant:

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

15
langpavel

Pour l'espace réservé d'entrée pour plus détails

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

Sur la base du react intl wiki , la mise en œuvre d'une zone de saisie avec un paramètre fictif traduisible ressemblera à

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

et l'utilisation de celui-ci:

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

La partie id: 'myPlaceholderText', est nécessaire pour permettre à babel-plugin-react-intl de collecter les messages à traduire.

1
gazdagergo

Vous essayez de rendre un composant React nommé FormattedMessage dans une balise fictive qui attend une chaîne.

Vous devriez plutôt créer une fonction nommée FormattedMessage qui renvoie une chaîne dans l'espace réservé.

function FormattedMessage(props) {
    ...
}

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

Dans mon cas, l'application entière se trouvait dans un seul fichier, donc utiliser export ne fonctionnerait pas. Celui-ci utilise la structure de classe normale afin que vous puissiez utiliser l'état et d'autres fonctionnalités de React si nécessaire.

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

const nameInput = injectIntl(nameInputOrig);

Appliquer à l'aide de la constante créée:

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