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
から各MyButton
に state を渡し、共有のクリックハンドラも一緒に渡す。
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 をコンポーネント間で共有できました。