JSX に波括弧で JavaScript を含める

JSX により、JavaScript ファイル内に HTML のようなマークアップを書いて、レンダリングロジックとコンテンツを同じ場所にまとめられるようになります。ときに、そのマークアップの中で JavaScript のロジックを書いたり動的なプロパティを参照したりしたくなることがあります。このような場合、JSX 内で波括弧を使うことで、JavaScript への入り口を開くことができます。

このページで学ぶこと

  • 引用符を使って文字列を渡す方法
  • 波括弧を使って JSX 内で JavaScript 変数を参照する方法
  • 波括弧を使って JSX 内で JavaScript 関数を呼び出す方法
  • 波括弧を使って JSX 内でオブジェクトを利用する方法

引用符で文字列を渡す

JSX に文字列の属性を渡したい場合、それをシングルクオートかダブルクオートで囲みます:

export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}

この例では "https://i.imgur.com/7vQD0fPs.jpg""Gregorio Y. Zara" が文字列として渡されています。

では srcalt のテキストを動的に指定したい場合はどうすればいいのでしょう? ""{} に置き換えることで、JavaScript の値を使うことができるのです:

export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}

className="avatar""avatar" という CSS クラス名を指定して画像を円形にしており、src={avatar}avatar という名前の JavaScript 変数を読み出している、という違いに注意してください。波括弧を使うことで、マークアップの中で直接 JavaScript を使えるようになるからです。

波括弧は JavaScript 世界への窓口

JSX とは JavaScript を書く特殊な方法のひとつです。つまりその中で JavaScript が使えるということであり、そのための手段が波括弧 {} です。以下の例では、とある科学者の名前を name として宣言し、それを <h1> 内に波括弧を使って埋め込んでいます:

export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}

name の値を 'Gregorio Y. Zara' から 'Hedy Lamarr' にしてみてください。To Do リストのタイトルが変わりましたか?

波括弧の中では formatDate() のような関数呼び出しも含む、あらゆる JavaScript の式が動作します:

const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}

波括弧を使える場所

JSX 内部で波括弧を使う方法は 2 つだけです:

  1. テキストとして、JSX タグの中で直接使う:<h1>{name}'s To Do List</h1> は動作しますが <{tag}>Gregorio Y. Zara's To Do List</{tag}> は動作しない。
  2. 属性として= 記号の直後に使う:src={avatar}avatar という変数を読み出すが、 src="{avatar}" と書くと "{avatar}" という文字列そのものを渡す。

「ダブル波括弧」で JSX 内に CSS やその他のオブジェクトを含める

文字列や数字、その他の JavaScript の式に加えて、オブジェクトを JSX に渡すこともできます。オブジェクトも波括弧を使って { name: "Hedy Lamarr", inventions: 5 } のように記述しますね。ですので JS オブジェクトを JSX に渡すときには、オブジェクトを別の波括弧のペアでラップして、person={{ name: "Hedy Lamarr", inventions: 5 }} のようにする必要があります。

これは JSX 内でインラインの CSS スタイルを使うときに目にすることがあります。React でインラインスタイルを使わなければいけないわけではありません(大抵の場合は CSS クラスでうまくいきます)。しかしインラインスタイルが必要な場合は、style 属性にオブジェクトを渡します:

export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}

backgroundColorcolor の値を変更してみてください。

以下のように書けば波括弧の中に書かれた JavaScript のオブジェクトがよく見えてくるでしょう:

<ul style={
{
backgroundColor: 'black',
color: 'pink'
}
}>

次に {{}} を見たときには、JSX の波括弧の中に書かれたオブジェクトに過ぎないということを思い出してください!

落とし穴

インラインの style 属性はキャメルケースで書きます。例えば HTML で <ul style="background-color: black"> となっていれば、あなたのコンポーネントでは <ul style={{ backgroundColor: 'black' }}> になります。

オブジェクトと波括弧でさらにいろいろやってみる

複数の式をひとつのオブジェクト内に移動して、JSX の波括弧内から参照することができます:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

この例では person という JavaScript オブジェクト内に name 文字列と theme オブジェクトが含まれています。

const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};

コンポーネントは person から始めて以下のように書くことでこれらの値を使うことができます:

<div style={person.theme}>
<h1>{person.name}'s Todos</h1>

JSX ではデータやロジックを書くのに JavaScript を使うため、JSX はテンプレート言語としては非常にミニマルです。

まとめ

これで JSX についてのほとんどを学びました:

  • 引用符内に書かれた JSX 属性は文字列として渡される。
  • 波括弧を使えば JavaScript のロジックや変数をマークアップ内に含めることができる。
  • 波括弧はタグのコンテンツの中で使うか、属性の場合は = の直後で使う。
  • {{}} は特別な構文ではなく、JSX の波括弧にくっつくように書かれた JavaScript オブジェクトである。

チャレンジ 1/3:
間違いを修正する

以下のコードは Objects are not valid as a React child というエラーを出してクラッシュします:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

どこが問題か分かりますか?