クイックスタート
React ドキュメントへようこそ!このページでは、日常的に使用する React の概念の 80% について紹介します。
以下の内容を学習します
- コンポーネントを作成し、ネストする方法
- マークアップとスタイルを追加する方法
- データを表示する方法
- 条件とリストをレンダリングする方法
- イベントに応答し、画面を更新する方法
- コンポーネント間でデータを共有する方法
コンポーネントの作成とネスト
React アプリは *コンポーネント* で構成されています。コンポーネントとは、独自のロジックと外観を持つ UI (ユーザーインターフェース) の一部です。コンポーネントは、ボタンのように小さなものから、ページ全体のように大きなものまであります。
React コンポーネントは、マークアップを返す JavaScript 関数です。
function MyButton() {
return (
<button>I'm a button</button>
);
}
MyButton
を宣言したので、別のコンポーネントにネストできます。
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
<MyButton />
は大文字で始まっていることに注意してください。これが React コンポーネントであることを示しています。React コンポーネント名は常に大文字で始まる必要がありますが、HTML タグは小文字である必要があります。
結果を見てみましょう
function MyButton() { return ( <button> I'm a button </button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton /> </div> ); }
export default
キーワードは、ファイル内のメインコンポーネントを指定します。JavaScript 構文の一部に慣れていない場合は、MDN と javascript.info に優れたリファレンスがあります。
JSX によるマークアップの記述
上記のマークアップ構文は、*JSX* と呼ばれます。JSX はオプションですが、ほとんどの React プロジェクトでは、その利便性から JSX を使用しています。ローカル開発に推奨されるすべてのツールは、JSX をすぐにサポートしています。
JSX は HTML よりも厳密です。<br />
のようにタグを閉じる必要があります。また、コンポーネントは複数の JSX タグを返すことができません。<div>...</div>
や空の <>...</>
ラッパーのように、共通の親要素でラップする必要があります。
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
JSX に移植する HTML が大量にある場合は、オンラインコンバーターを使用できます。
スタイルの追加
React では、className
を使用して CSS クラスを指定します。これは、HTML の class
属性と同じように機能します。
<img className="avatar" />
次に、別の CSS ファイルに 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"
は"avatar"
という文字列をCSSクラスとして渡しますが、src={user.imageUrl}
はJavaScriptのuser.imageUrl
変数の値を読み取り、その値をsrc
属性として渡します。
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
JSX中括弧内に、たとえば文字列連結など、より複雑な式を記述することもできます。
const user = { name: 'Hedy Lamarr', imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg', imageSize: 90, }; export default function Profile() { return ( <> <h1>{user.name}</h1> <img className="avatar" src={user.imageUrl} alt={'Photo of ' + user.name} style={{ width: user.imageSize, height: user.imageSize }} /> </> ); }
上記の例では、style={{}}
は特別な構文ではなく、style={ }
JSX中括弧内の通常の{}
オブジェクトです。スタイルがJavaScript変数に依存する場合、style
属性を使用できます。
条件付きレンダリング
Reactには、条件を記述するための特別な構文はありません。代わりに、通常のJavaScriptコードを記述するときと同じ手法を使用します。たとえば、if
文を使用して、JSXを条件付きで含めることができます。
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機能に依存します。
たとえば、製品の配列があるとします。
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
コンポーネント内で、map()
関数を使用して、製品の配列を<li>
アイテムの配列に変換します。
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
<li>
にkey
属性があることに注目してください。リストの各アイテムについて、そのアイテムを兄弟の中で一意に識別する文字列または数値を渡す必要があります。通常、キーはデータベースIDなどのデータから取得する必要があります。Reactは、後でアイテムを挿入、削除、または並べ替えた場合に何が起こったかを把握するためにキーを使用します。
const products = [ { title: 'Cabbage', isFruit: false, id: 1 }, { title: 'Garlic', isFruit: false, id: 2 }, { title: 'Apple', isFruit: true, id: 3 }, ]; export default function ShoppingList() { const listItems = products.map(product => <li key={product.id} style={{ color: product.isFruit ? 'magenta' : 'darkgreen' }} > {product.title} </li> ); return ( <ul>{listItems}</ul> ); }
イベントへの応答
コンポーネント内にイベントハンドラ関数を宣言することで、イベントに応答できます。
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
onClick={handleClick}
の最後に括弧がないことに注目してください!イベントハンドラ関数を呼び出すのではなく、渡すだけが必要です。ユーザーがボタンをクリックすると、Reactがイベントハンドラを呼び出します。
画面の更新
多くの場合、コンポーネントにいくつかの情報を「記憶」させて表示したいことがあります。たとえば、ボタンがクリックされた回数をカウントしたい場合があります。これを行うには、コンポーネントに状態を追加します。
まず、ReactからuseState
をインポートします。
import { useState } from 'react';
これで、コンポーネント内に状態変数を宣言できます。
function MyButton() {
const [count, setCount] = useState(0);
// ...
useState
からは2つのものが得られます。現在の状態(count
)と、それを更新できる関数(setCount
)です。任意の名前を付けることができますが、慣例として[何か、set何か]
のように記述します。
ボタンが最初に表示されるとき、count
は 0
になります。これは、0
を useState()
に渡したためです。状態を変更したい場合は、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
になります。以下同様です。
同じコンポーネントを複数回レンダリングする場合、それぞれが独自のステートを持ちます。各ボタンを個別にクリックしてください。
import { useState } from 'react'; export default function MyApp() { return ( <div> <h1>Counters that update separately</h1> <MyButton /> <MyButton /> </div> ); } function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick}> Clicked {count} times </button> ); }
各ボタンが自身の count
ステートを「記憶」し、他のボタンに影響を与えないことに注目してください。
フックの使用
use
で始まる関数は、*フック*と呼ばれます。useState
は、React によって提供される組み込みフックです。他の組み込みフックは、API リファレンスにあります。既存のフックを組み合わせて、独自のフックを作成することもできます。
フックは他の関数よりも制限があります。フックはコンポーネント(または他のフック)の*最上位*でのみ呼び出すことができます。条件やループ内で useState
を使用したい場合は、新しいコンポーネントを抽出してそこに配置します。
コンポーネント間でのデータの共有
前の例では、各 MyButton
は独自の独立した count
を持っており、各ボタンがクリックされたとき、クリックされたボタンの count
のみが変更されました。


最初に、各 MyButton
の count
ステートは 0
です。


最初の MyButton
は、その count
を 1
に更新します。
ただし、多くの場合、コンポーネントは*データを共有し、常に一緒に更新する*必要があります。
両方の MyButton
コンポーネントが同じ count
を表示し、一緒に更新するには、個々のボタンからそれらすべてを含む最も近いコンポーネントにステートを「上方に」移動する必要があります。
この例では、それは MyApp
です。


最初に、MyApp
の count
ステートは 0
で、両方の子に渡されます。


クリックすると、MyApp
はその count
ステートを 1
に更新し、両方の子に渡します。
これで、どちらかのボタンをクリックすると、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
関数に設定されているため、その中のコードが実行されます。そのコードは setCount(count + 1)
を呼び出し、count
ステート変数をインクリメントします。新しい count
値は prop として各ボタンに渡されるため、すべて新しい値が表示されます。これは「ステートの持ち上げ」と呼ばれます。ステートを上に移動することで、コンポーネント間で共有しました。
import { useState } from 'react'; 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> ); } function MyButton({ count, onClick }) { return ( <button onClick={onClick}> Clicked {count} times </button> ); }