web-dev-qa-db-ja.com

React-Intl入力プレースホルダーでFormattedMessageを使用する方法

から値を取得する方法がわかりません

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

入力のようなプレースホルダー形式に:

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

実際のプレースホルダーで[オブジェクトオブジェクト]を返すためです。実際の正しい値を取得する方法はありますか?

44
Bryan

<Formatted... />react-intl Reactコンポーネントは、レンダリングシナリオで使用するためのものであり、プレースホルダー、代替テキストなどで使用するためのものではありません。プレーンテキストではなくHTMLをレンダリングします、これはシナリオでは役に立ちません。

代わりに、react-intlは、まったく同じ理由で 低レベルAPI を提供します。レンダリングコンポーネント自体は、このAPIを内部で使用して、値をHTMLにフォーマットします。シナリオでは、おそらく下位レベルのformatMessage(...) AP​​Iを使用する必要があります。

intl HOCを使用してinjectIntlオブジェクトをコンポーネントに挿入し、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機能を使用していることに注意してください。設定に応じて調整してください。

82
lsoliveira
  • intl HoCからinjectIntl propを使用できます
  • 子コンポーネントとして機能を提供することもできます:
<FormattedMessage {...messages.placeholderIntlText}>
  {(msg) => (<input placeholder={msg} />)}
</FormattedMessage>
23
langpavel

入力プレースホルダーFor more details

   <FormattedMessage id="yourid" defaultMessage="search">
    {placeholder=>  
        <Input placeholder={placeholder}/>
        }
    </FormattedMessage>
7

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 を有効にするために必要です。

2
gazdagergo

2019年7月で、react-intl 3ベータには seIntl フックが同梱されており、これらの種類の翻訳が簡単になります:

import React from 'react';
import {useIntl, FormattedDate} from 'react-intl';

const FunctionComponent: React.FC<{date: number | Date}> = ({date}) => {
  const intl = useIntl();
  return (
    <span title={intl.formatDate(date)}>
      <FormattedDate value={date} />
    </span>
  );
};

export default FunctionComponent;

そして、APIが提供するメソッドを使用するカスタムフックを作成できます。

import { useIntl } from 'react-intl'

export function useFormatMessage(messageId) {
  return useIntl().formatMessage({ id: messageId })
}
1
Finrod

FormattedMessageという名前のReactコンポーネントを、文字列が必要なプレースホルダータグにレンダリングしようとしています。

代わりに、プレースホルダーに文字列を返すFormattedMessageという名前の関数を作成する必要があります。

function FormattedMessage(props) {
    ...
}

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

私の場合、アプリ全体を1つのファイルに収めていたため、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 />
    }
}
0
aksu

@gazdagergの答えから始めて、私は彼のコードを次のように適合させました:

  • inputのラッパーである新しいコンポーネントを持つ
  • ロケールconfから文字列のIDを受け取ります
  • iDに基づいて、グローバルロケール設定に関する文字列を返します
  • 文字列IDが設定されていない場合の処理​​(これにより例外とページがクラッシュしました)

    import React from 'react';
    import { injectIntl, intlShape, defineMessages } from 'react-intl';


    const InputWithPlaceholder = ({ intl, placeholder }) => {

      const messages = defineMessages({
        placeholder: {
          id: placeholder,
          defaultMessage: '',
        },
      });

      if(messages.placeholder.id) {
        return (
          <input placeholder={ intl.formatMessage(messages.placeholder) } />
        );
      } else {
        return (
          <input/>
        );
      }
    };

    InputWithPlaceholder.propTypes = {
      intl: intlShape.isRequired
    };

    export default injectIntl(InputWithPlaceholder);

次の方法で他のファイルで使用できます。

  1. 新しいコンポーネントをインポートする
  2. ロケール文字列のIDをパラメーターとして使用します
import InputWithIntlPlaceholder from 'your/path/to/component/InputWithIntlPlaceholder';

... more code here ...

<InputWithIntlPlaceholder placeholder="your.locale.string.id" />
0
Victor