公式の日本語訳版が出たので、本記事は非推奨とします。
https://ja.react.dev/
本記事はReact公式サイトのQuick Startを翻訳したものですが、非公式の日本語ドキュメントです。
ようこそ、Reactドキュメントへ!このページでは日常的に使うことになるReactの概念の80%を紹介します。
学べること
- コンポーネントの作成とネストする方法
- マークアップとスタイルの追加方法
- データの表示方法
- 条件とリストのレンダー方法
- イベントと画面の更新に反応する方法
- コンポーネント間のデータの受け渡し方法
コンポーネントの作り方とネストさせる方法
Reactアプリはコンポーネントから作られます。一つのコンポーネントは独自のロジックや表示を持ったUI(ユーザーインターフェース)の一部です。コンポーネントはボタンぐらいの小ささ、もしくはページ全体のぐらいの大きさになることができます。
Reactコンポーネントはマークアップを返すJavaScriptの関数です。
function MyButton() {
return (
<button>I'm a button</button>
);
}
MyButton
を宣言しているときに、MyButton
を他のコンポーネントに入れてネストさせることができます。
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
<MyButton />
はアッパーケースであることに気をつけましょう。アッパーケースがReactコンポーネントであることを知る方法となります。Reactコンポーネントの命名は必ずアッパーケースで、HTMLタグはローワーケースでなければなりません。
この結果を見てください。
export default
は、ファイルの中でメインコンポーネントであることを定義するキーワードです。もしJavaScriptの構文に詳しくなければ、MDNとjavascript.infoがいいリファレンスになります。
JSXを使ったマークアップの書き方
上で見たマークアップ構文はJSXと呼ばれています。JSXは1つの選択肢ですが、利便性の点で多くのReactプロジェクトではJSXを使うことが多いです。私たちがローカル開発で推奨するもの全ては、JSXを使えるようにサポートしています。
JSXはHTMLよりも厳密です。<br />
のように閉じタグにしなければなりません。また、コンポーネントは複数のJSXタグを返すことができません。<div>...</div>
もしくは<>...</>
の中に複数のJSXを入れる必要があります。
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
もし多くのHTMLをJSXに変換したいのであれば、online converterを使うことができます。
スタイルの追加
Reactでは、CSSのクラスをclassName
で定義します。HTMLのclass
属性と同じような方法で実装することができます。
<img className="avatar" />
分けたCSSファイルでスタイルを書くときは、このようになります。
/* In your CSS */
.avatar {
border-radius: 50%;
}
Reactは、CSSファイルの追加方法を定めていません。最もシンプルな方法だと、HTMLにlink
タグを追加する方法があります。もし、ビルドツールやフレームワークを使っているのであれば、各々のドキュメントを参照し、プロジェクトにCSSファイルを追加する方法を学んでください。
データの表示方法
JSXはマークアップをJavaScriptの中に入れることができます。コードから変数を埋め込み、ユーザーへ表示するために、中括弧を使うとJavaScriptの中にエスケープバックさせることができます。例えば、user.name
はこのように表示します。
return (
<h1>
{user.name}
</h1>
);
また、JSXの属性からJavaScript内でエスケープすることもできますが、クウォートの代わりに中括弧を使う必要があります。例えば、className="avatar"
はCSSクラスとして"avatar"
文字列を渡していますが、src={user.imageUrl}
はJavaScriptのuser.imageUrl
変数を読み出し、src
属性に値を渡しています。
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
さらに複雑な構文をJSXの中括弧に入れることができます。例えば、文字列結合はこのようになります。
上の例で、style={{}}
は特別な構文ではないですが、一般的な{}
オブジェクトがstyle={ }
の中括弧に入っています。スタイルがJavaScriptの変数に依存するときに、style
属性を使うことができます。
条件付きレンダリング
Reactにおいて、条件を実装するための特別な構文はありません。代わりに、一般的なJavaScriptのコードを実装するときと同じように実装できます。例えば、条件分岐でJSXを含めるためにif
文を使うことができます。
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
よりコンパクトなコードの方がよければ、三項演算子を使うことができます。if
とは異なり、JSX内部で動作します。
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
else
の分岐が必要ないときは、&&
を使った構文で短くできます。
<div>
{isLoggedIn && <AdminPanel />}
</div>
これらの方法はすべて、属性を条件付きで指定する場合にも有効です。JavaScriptの構文に慣れていない方は、まずif...elseを常に使うところから始めるとよいでしょう。
配列のレンダリング
コンポーネントの配列をレンダーするために、for
ループやmap()
関数のようなJavaScriptの機能を使うことができます。
例えば、productsの配列を宣言します。
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
コンポーネント内で、products配列を<li>
アイテムの配列に変換するためには、map()
関数を使います。
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
<li>
がkey
属性を持っていることに注目してください。リストの各アイテムは、シブリング間でアイテム一意に識別する文字列または数値を渡す必要があります。通常、キーはデータベースIDのようなデータから取得する必要があります。Reactは、アイテムを追加、削除、並べ替えしたことを知るためにキーを使用します。
イベント反応
コンポーネント内でイベントハンドラーの関数を宣言することで、イベントに応答することができます。
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
onClick={handleClick}
では、最後に丸括弧を付けていないことに注目してください!イベントハンドラーの関数を呼び出さずに、関数を渡すだけで十分です。ボタンを押すときにイベントハンドラーは呼び出されます。
画面の更新
コンポーネントに情報を持たせて表示させたいことがよくあります。例えば、ボタンがクリックされた回数を数えたいということがあるでしょう。実現するには、コンポーネントにstateを追加します。
はじめに、ReactからuseState
をインポートします。
import { useState } from 'react';
すると、状態変数をコンポーネントの中で宣言することができます。
function MyButton() {
const [count, setCount] = useState(0);
useState
から、現在の状態変数(count)とcountを更新させる関数(setCount)の2つを取得しようとしています。どんな名前でも与えることができますが、[something, setSomething]
のように実装することが慣習です。
最初にボタンが表示されるときは、useState
に0
を渡しているためcount
は0
になります。stateを変えたいときは、setCount
を呼び出し新しい値を渡します。ボタンをクリックするとカウンターを増加させるにはこのように実装します。
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
Reactが一度コンポーネント関数を呼び出すとします。このとき、count
は1
になります。そして2
になり1ずつ増えていきます。同じコンポーネントを複数レンダーする場合は、それぞれが独立した状態変数になります。分けたボタンをどちらもクリックしてみましょう。
各々のボタンが自分のcount
状態を保持し、他のボタンには影響を与えていないことに注意してください。
フックスの使い方
useで始まる関数はフックスと呼ばれます。useStateはReactが提供する組み込みのフックです。APIリファレンスで他の組み込まれているフックスを見つけることができます。既存のフックスを組み合わせて自作のフックスを作成することも可能です。
フックスは他の関数よりも制約が多いです。フックスはコンポーネント(または他のHook)の先頭だけで呼び出すことができます。useStateを条件やループの中で使いたい場合は、新しいコンポーネントに切り出してください。
コンポーネント間のデータ共有
先ほどの例では、それぞれのMyButton
が自分のcount
を持っており、それぞれのボタンがクリックすることができ、クリックしたボタンのcount
のみが変化しました。
しかし、どちらもデータを共有し合い同期をするコンポーネントが必要となることがよくあります。
両方のMyButton
コンポーネントが同じカウントを表示し同期するには、個々のボタンの状態を「上へ」移動させ、すべてのボタンを含む最も近いコンポーネントに移動する必要があります。
MyApp
での例です。
これで、どちらともボタンをクリックするとき、MyApp
の中のcount
が変化し、MyButton
のどのカウントも変化することになります。これをコードで表現すると、次のようになります。
まず、MyButton
からMyApp
に状態を移動させます。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
// ... we're moving code from here ...
}
そして、MyApp
から各MyButton
へ、共有のクリックハンドラーと一緒に状態を渡します。上記で<img>
のような組み込みタグで行ったように、JSXの中括弧を使ってMyButton
に情報を渡すことができます。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update together</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
このように渡している情報のことをpropsと呼びます。このMyApp
コンポーネントはcount
状態とhandleClick
イベントハンドラーを含み、その両方を各ボタンにpropsとして渡しています。
最後に、親コンポーネントから受け取ったpropsを読み込めるようにMyButton
を変更します。
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}
ボタンをクリックするとき、onClick
ハンドラーが発火します。各ボタンのonClick
propはMyApp
内のhandleClick
関数に設定されたので、MyApp
内のコードが実行されます。そのコードではcount
状態変数をインクリメントするsetCount(count + 1)
を呼び出します。新しいcount
の値は、各ボタンにpropとして渡されるので、すべてのボタンに新しい値が表示されます。これを「状態を上に上げる」と言います。状態を上に上げることで、コンポーネント間で状態を共有させられます。
次のステップ
ここまでで、Reactを実装するための基本を知ることができました!
ここで学んだことを実践に活かすためにチュートリアルをチェックし、Reactで初めてのミニアプリを作ってみましょう。