AsaDesign

React:クイックスタート

このページで学ぶこと

  • コンポーネントの作成とネスト
  • マークアップとスタイルの追加
  • データの表示
  • 条件分岐とリストのレンダー
  • イベントへの応答と画面の更新
  • コンポーネント間でのデータの共有
https://ja.react.dev/learn

後で復習できるように、概要をまとめました。

コンポーネントの作成とネスト

  • Reactコンポーネントは大文字で始まる。<MyButton />
  • export default キーワードは、ファイル内のメインコンポーネントを指定している。

マークアップとスタイルの追加

  • JSXマークアップ構文の使用は任意だが、使うことがほとんど。
  • コンポーネントは複数の JSX タグを return することはできない。なので、一つの親要素でまとめなければいけない。<></>
  • React では、CSS クラスを className で指定する。<img className=”avatar” />

データの表示・・・波括弧を使う

  • 波括弧を使えばJSX内でJavaScriptに戻ることができる。{user.name}
  • JSX の属性 (attribute) の部分から JavaScript に戻ることもできる。src={user.imageUrl}
  • JSX の波括弧の中に、文字の連結などもっと複雑な式を入れることもできる。alt={‘Photo of ‘ + user.name}
  • スタイルが JavaScript 変数に依存する場合は、style 属性を使うことができる。style={{width: user.imageSize, height: user.imageSize}}

条件分岐とリスト(繰り返し)のレンダー

条件分岐(if)

  • JavaScriptのif文の中にJSXを含めることができる。
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
  • 逆に三項演算子は、JSXの中で動作する。
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>
  • elseが不要な時はこうしてもいい。
<div>
  {isLoggedIn && <AdminPanel />}
</div>

繰り返し処理(for, map)

  • liの中のkeyに注目。各データには、それぞれを識別するための文字列か数値を持たせる必要がある。データベースのIDなどを使うといい。
const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);

イベントへの応答と画面の更新

イベントへの応答

  • コンポーネントの中でイベントハンドラ関数というものを宣言することで、イベントに応答できる。
    イベントハンドラ関数=handleClick()?
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

画面の更新

  • コンポーネントに情報を記憶させたいとき、stateを使う。

まず、React から useState をインポートする。

import { useState } from 'react';

これで、コンポーネント内に state 変数を宣言できる。

function MyButton() {
  const [count, setCount] = useState(0);
  // ...

useState からは 2 つのものが得られます。現在の state (count) と、それを更新するための関数 (setCount) です。名前は何でも構いませんが、慣習的には [something, setSomething] のように記述します。

  • 各ボタンがそれぞれ count という state を「記憶」し、他のボタンには影響を与えない。

フックの使用 

  • useState などuse で始まる関数は、React が提供する組み込みのフック。
  • 既存のフックを組み合わせて独自のフックを作成することもできる。
  • フックはコンポーネントのトップレベル(または他のフック内)でのみ呼び出すことができる。
  • 条件分岐やループの中で useState を使いたい場合は、新しいコンポーネントを抽出してそこに配置する。

コンポーネント間でのデータの共有(&ここまでの総復習)

  • 各ボタンの動きを連動させたい場合はボタンではなく、共通の親コンポーネントに状態(state)を持たせる。
// メインのコンポーネント:export default
export default function MyApp() {

  // 状態保持のフックの使用:useState
  // state変数の使用
  const [count, setCount] = useState(0);

  // イベントハンドラ関数:handleClick()
  function handleClick() {
    // 画面更新の関数:setCount
    setCount(count + 1);
  }
  • MyApp から各 MyButtonstate を渡し、共有のクリックハンドラも一緒に渡す。
return (
    <div>
      <h1>Counters that update separately</h1>
      {/* 波括弧でデータを渡す。
          handleClickを仕込むことで、子コンポーネントで
          イベント発火させることができるようになっている。 */}
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

このように渡される情報は props と呼ばれる。MyApp コンポーネントは count 状態と handleClick イベントハンドラを保持しており、それらをどちらも props として各ボタンに渡す。

  • 最後に、MyButton を変更して、親コンポーネントから渡された props を読み込むようにする。
// 親コンポーネントからprops(countとonClick)を受け取っている
function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

ボタンをクリックすると、onClick ハンドラが発火します。
各ボタンの onClick プロパティは MyApp 内の handleClick 関数となっているので、その中のコードが実行されます。
そのコードは setCount(count + 1) を呼び出し、count という state 変数をインクリメントします。新しい count の値が各ボタンに props として渡されるため、すべてのボタンに新しい値が表示されます。
この手法は「state のリフトアップ(持ち上げ)」と呼ばれています。リフトアップすることで、state をコンポーネント間で共有できました。