クイックスタート - New React Docs (日本語翻訳)

:::note warn
公式の日本語訳版が出たので、本記事は非推奨とします。
https://ja.react.dev/
:::

:::note
本記事はReact公式サイトの[Quick Start](https://react.dev/learn)を翻訳したものですが、非公式の日本語ドキュメントです。
:::

ようこそ、Reactドキュメントへ！このページでは日常的に使うことになるReactの概念の80%を紹介します。

**学べること**

- コンポーネントの作成とネストする方法
- マークアップとスタイルの追加方法
- データの表示方法
- 条件とリストのレンダー方法
- イベントと画面の更新に反応する方法
- コンポーネント間のデータの受け渡し方法

# コンポーネントの作り方とネストさせる方法
Reactアプリはコンポーネントから作られます。一つのコンポーネントは独自のロジックや表示を持ったUI（ユーザーインターフェース）の一部です。コンポーネントはボタンぐらいの小ささ、もしくはページ全体のぐらいの大きさになることができます。

Reactコンポーネントはマークアップを返すJavaScriptの関数です。

```react
function MyButton() {
  return (
    <button>I'm a button</button>
  );
}
```

`MyButton`を宣言しているときに、`MyButton`を他のコンポーネントに入れてネストさせることができます。

```react
export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}
```

`<MyButton />`はアッパーケースであることに気をつけましょう。アッパーケースがReactコンポーネントであることを知る方法となります。Reactコンポーネントの命名は必ずアッパーケースで、HTMLタグはローワーケースでなければなりません。

この結果を見てください。

https://codesandbox.io/embed/peaceful-meninsky-ieh8uf?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

`export default`は、ファイルの中でメインコンポーネントであることを定義するキーワードです。もしJavaScriptの構文に詳しくなければ、[MDN](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export)と[javascript.info](https://javascript.info/import-export)がいいリファレンスになります。

# JSXを使ったマークアップの書き方
上で見たマークアップ構文はJSXと呼ばれています。JSXは1つの選択肢ですが、利便性の点で多くのReactプロジェクトではJSXを使うことが多いです。[私たちがローカル開発で推奨するもの](https://react.dev/learn/installation)全ては、JSXを使えるようにサポートしています。

JSXはHTMLよりも厳密です。`<br />`のように閉じタグにしなければなりません。また、コンポーネントは複数のJSXタグを返すことができません。`<div>...</div>`もしくは`<>...</>`の中に複数のJSXを入れる必要があります。

```react
function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}
```

もし多くのHTMLをJSXに変換したいのであれば、[online converter](https://transform.tools/html-to-jsx)を使うことができます。

# スタイルの追加
Reactでは、CSSのクラスを`className`で定義します。HTMLの[`class`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class)属性と同じような方法で実装することができます。

```react
<img className="avatar" />
```

分けたCSSファイルでスタイルを書くときは、このようになります。

```css
/* In your CSS */
.avatar {
  border-radius: 50%;
}
```

Reactは、CSSファイルの追加方法を定めていません。最もシンプルな方法だと、HTMLに[`link`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)タグを追加する方法があります。もし、ビルドツールやフレームワークを使っているのであれば、各々のドキュメントを参照し、プロジェクトにCSSファイルを追加する方法を学んでください。

# データの表示方法
JSXはマークアップをJavaScriptの中に入れることができます。コードから変数を埋め込み、ユーザーへ表示するために、中括弧を使うとJavaScriptの中にエスケープバックさせることができます。例えば、`user.name`はこのように表示します。

```react
return (
  <h1>
    {user.name}
  </h1>
);
```

また、JSXの属性からJavaScript内でエスケープすることもできますが、クウォートの代わりに中括弧を使う必要があります。例えば、`className="avatar"`はCSSクラスとして`"avatar"`文字列を渡していますが、`src={user.imageUrl}`はJavaScriptの`user.imageUrl`変数を読み出し、`src`属性に値を渡しています。

```react
return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);
```

さらに複雑な構文をJSXの中括弧に入れることができます。例えば、[文字列結合](https://javascript.info/operators#string-concatenation-with-binary)はこのようになります。

https://codesandbox.io/embed/serene-curie-15oriv?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

上の例で、`style={{}}`は特別な構文ではないですが、一般的な`{}`オブジェクトが`style={ }`の中括弧に入っています。スタイルがJavaScriptの変数に依存するときに、`style`属性を使うことができます。

# 条件付きレンダリング
Reactにおいて、条件を実装するための特別な構文はありません。代わりに、一般的なJavaScriptのコードを実装するときと同じように実装できます。例えば、条件分岐でJSXを含めるために`if`文を使うことができます。

```react
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

```

よりコンパクトなコードの方がよければ、[三項演算子](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)を使うことができます。`if`とは異なり、JSX内部で動作します。

```react
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>
```

`else`の分岐が必要ないときは、[`&&`を使った構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#short-circuit_evaluation)で短くできます。

```react
<div>
  {isLoggedIn && <AdminPanel />}
</div>
```

これらの方法はすべて、属性を条件付きで指定する場合にも有効です。JavaScriptの構文に慣れていない方は、まずif...elseを常に使うところから始めるとよいでしょう。

# 配列のレンダリング
コンポーネントの配列をレンダーするために、[`for`ループ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for)や[`map()`関数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)のようなJavaScriptの機能を使うことができます。

例えば、productsの配列を宣言します。

```react
const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];
```

コンポーネント内で、products配列を`<li>`アイテムの配列に変換するためには、`map()`関数を使います。

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

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

`<li>`が`key`属性を持っていることに注目してください。リストの各アイテムは、シブリング間でアイテム一意に識別する文字列または数値を渡す必要があります。通常、キーはデータベースIDのようなデータから取得する必要があります。Reactは、アイテムを追加、削除、並べ替えしたことを知るためにキーを使用します。

https://codesandbox.io/embed/xenodochial-bell-xtczu1?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

# イベント反応

コンポーネント内でイベントハンドラーの関数を宣言することで、イベントに応答することができます。

```react
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

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

`onClick={handleClick}`では、最後に丸括弧を付けていないことに注目してください！イベントハンドラーの関数を呼び出さずに、関数を渡すだけで十分です。ボタンを押すときにイベントハンドラーは呼び出されます。

# 画面の更新
コンポーネントに情報を持たせて表示させたいことがよくあります。例えば、ボタンがクリックされた回数を数えたいということがあるでしょう。実現するには、コンポーネントに*state*を追加します。

はじめに、Reactから[`useState`](https://react.dev/reference/react/useState)をインポートします。

```react
import { useState } from 'react';
```

すると、状態変数をコンポーネントの中で宣言することができます。

```react
function MyButton() {
  const [count, setCount] = useState(0);
```

`useState`から、現在の状態変数(count)とcountを更新させる関数(setCount)の2つを取得しようとしています。どんな名前でも与えることができますが、`[something, setSomething]`のように実装することが慣習です。

最初にボタンが表示されるときは、`useState`に`0`を渡しているため`count`は`0`になります。stateを変えたいときは、`setCount`を呼び出し新しい値を渡します。ボタンをクリックするとカウンターを増加させるにはこのように実装します。

```react
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ずつ増えていきます。同じコンポーネントを複数レンダーする場合は、それぞれが独立した状態変数になります。分けたボタンをどちらもクリックしてみましょう。

https://codesandbox.io/embed/elated-vaughan-1ghtss?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

各々のボタンが自分の`count`状態を保持し、他のボタンには影響を与えていないことに注意してください。

# フックスの使い方
useで始まる関数はフックスと呼ばれます。useStateはReactが提供する組み込みのフックです。[APIリファレンス](https://react.dev/reference/react)で他の組み込まれているフックスを見つけることができます。既存のフックスを組み合わせて自作のフックスを作成することも可能です。

フックスは他の関数よりも制約が多いです。フックスはコンポーネント（または他のHook）の先頭だけで呼び出すことができます。useStateを条件やループの中で使いたい場合は、新しいコンポーネントに切り出してください。

# コンポーネント間のデータ共有

先ほどの例では、それぞれの`MyButton`が自分の`count`を持っており、それぞれのボタンがクリックすることができ、クリックしたボタンの`count`のみが変化しました。

![スクリーンショット 2023-03-28 0.41.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243199/fd613587-f91f-6507-0078-e0186c0192d2.png)

しかし、どちらもデータを共有し合い同期をするコンポーネントが必要となることがよくあります。

両方の`MyButton`コンポーネントが同じカウントを表示し同期するには、個々のボタンの状態を「上へ」移動させ、すべてのボタンを含む最も近いコンポーネントに移動する必要があります。

`MyApp`での例です。

![スクリーンショット 2023-03-28 0.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243199/313ccc28-1f02-55d3-64bc-00a2ede40ad1.png)

これで、どちらともボタンをクリックするとき、`MyApp`の中の`count`が変化し、`MyButton`のどのカウントも変化することになります。これをコードで表現すると、次のようになります。

まず、`MyButton`から`MyApp`に状態を移動させます。

```react
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`に情報を渡すことができます。

```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>
  );
}
```

このように渡している情報のことをpropsと呼びます。この`MyApp`コンポーネントは`count`状態と`handleClick`イベントハンドラーを含み、その両方を各ボタンにpropsとして渡しています。

最後に、親コンポーネントから受け取ったpropsを読み込めるように`MyButton`を変更します。

```react
function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}
```

ボタンをクリックするとき、`onClick`ハンドラーが発火します。各ボタンの`onClick`propは`MyApp`内の`handleClick`関数に設定されたので、`MyApp`内のコードが実行されます。そのコードでは`count`状態変数をインクリメントする`setCount(count + 1)`を呼び出します。新しい`count`の値は、各ボタンにpropとして渡されるので、すべてのボタンに新しい値が表示されます。これを「状態を上に上げる」と言います。状態を上に上げることで、コンポーネント間で状態を共有させられます。

https://codesandbox.io/embed/keen-hertz-sqqsbh?fontsize=14&hidenavigation=1&module=%2FApp.js&theme=dark

# 次のステップ
ここまでで、Reactを実装するための基本を知ることができました！
ここで学んだことを実践に活かすために[チュートリアル](https://react.dev/learn/tutorial-tic-tac-toe)をチェックし、Reactで初めてのミニアプリを作ってみましょう。