Reactの公式ドキュメントの理解（クイックスタート編）

Reactを独学で学ぶ上で、いちばん最初に公式ドキュメントの理解から着手しようと思ったのでアウトプットも兼ねて内容をまとめました。
ここではReact公式ドキュメントの「**クイックスタート**」をまとめました。

# こんな人向け
- Reactを触ったことがない人
- Reactに興味があり、学ぼうとしている
- Reactの概念・仕組みを知りたい

# 1.Reactとは
Reactは、Facebookによって開発されたオープンソースのJavaScriptライブラリです。
ユーザインタフェースを構築するために使用され、
「コンポーネント」と呼ばれる小さく独立した部品から組み立てることができます。

# 2.コンポーネント
>Reactアプリはコンポーネントで構成されています。コンポーネントとは、独自のロジックと外見を持つUIの部品のことです。コンポーネントは、ボタンのような小さなものである場合も、ページ全体を表す大きなものである場合もあります

Reactにおけるコンポーネントとは、マークアップを返すJavaScript関数のことです。
```jsx
function MyButton() {
 return (
  <button>I'm a button</button>
 );
}
```
```<MyButton />```を宣言すると、別のコンポーネントにネストできます。
```jsx
 export default funciton MyApp() {
  return (
    <div>
     <h1>Welcome to my app</h1>
     <MyButton /> // 宣言
    </div>
  );
}
```
:::note warn
 \<MyButton /\>のように大文字で始めることによって、Reactのコンポーネントであるということを示しています。Reactのコンポーネント名は常に大文字で始める必要があり、HTMLタグは小文字でなければいけません。
:::
ですので下記のように書く必要があります。
```App.tsx
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ってなに？となる人は[export defaultってなんだろう](https://qiita.com/rena_m/items/b9e79dc88e5c5bc5b245)を見ると分かりやすいです。

# 3.Reactで使用するマークアップ言語JSX
上で見たマークアップ言語は、JSXと呼ばれるものです。
JSXはHTMLより構文が厳格で、\<br /\>のようにタグは閉じる必要があります。また、コンポーネントは複数のJSXタグをreturnすることはできません。\<div\>...\</div\> や空の \<\>...\</\> ラッパのような共通の親要素で囲む必要があります。
```jsx
function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}
```
### スタイルの追加
Reactでは、CSSクラスを ```className``` で指定します。HTMLの ```class``` 属性と同じ方法で動作します。
```jsx
<img className="avatar" />
```
スタイルは別のCSSファイルに対応するCSSルールを記述します。
```css
.avatar {
  border-radius: 50%;
}
```
ReactにはCSSファイルの追加方法に関する規則はありません。
もし、CSSの記法を確認しながらコーディングしたい場合、HTMLに ```<link>``` タグを追加しておくと便利です。

### データの表示
JSXを使用することで、JavaScript内にマークアップを入れることができます。```{}``` を使うことで、JavaScriptに「戻る」ことができ、コード内の変数を埋め込んでユーザに表示することができます。
たとえば、以下は ```user.name``` を表示します。
```jsx
return (
  <h1>
    {user.name}
  </h1>
);
```
JSXの属性の部分からでもJavaScriptに「戻る」こともできます。
こちらも```{}```を使用する必要があります。例えば、```className="avator"``` はCSSクラスとして ```"avator"``` 文字列を渡すものですが、```src={user.imageUrl}``` はJavaScriptの ```user.imageUrl``` 変数の値を読み込み、その値を ```src``` 属性として渡します。
```jsx
return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);
```
JSXの```{}```の中にもっと複雑な指揮を入れることもできます。例えば、文字列の連結ができます。
```App.tsx
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の波括弧内にある```{}```オブジェクトです。スタイルがJavaSript変数に依存する場合は、```style``` 属性を使うことができます。
### 条件付きレンダー
Reactには、条件分岐を書くための特別な構文は存在しません。代わりに、通常のJavaScriptコードを書くときに使うのと同じ手法を使います。例えば、```if``` ステートメントを使って条件付きでJSXを含めることができます。
```jsx
let content;
if (isLoggedIn) {
 content = <AsminPanel />;
} else {
 content = <LoginForm />;
}
return (
 <div>
    {content}
 </div>
);
```
もっとコンパクトにしたい場合、```条件 ? 演算子``` を使用できます。```if``` とは異なり、JSXの中で動作します。
```jsx
<div>
 {isLoggedIn ? (
    <AsminPanel />
 ) : (
    <LoginForm />
 )}
</div>
```
```else```側の分岐が不要な場合は、短い ```論理 && 構文``` を使用することもできます。
```jsx
<div>
 {isLoggedIn && <AdminPanel />}
</div>
```
これらは、属性を条件付きで指定する場合に役立ちます。
### リストのレンダー
> コンポーネントのリストをレンダーする場合は、```forループ``` や ```配列のmap()関数``` といったJavaScriptの機能を使って行います。

例えばこのような商品の配列があるとします。
```jsx
const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];
```
コンポーネント内で、```map()``` 関数を使って商品の配列を ```<li>``` 要素の配列に変換します。
```jsx
const listItems = products.map(product => 
 <li key={product.id}>
    {product.title}
 </li>
);

return (
 <ul>{listItems}</ul>
);
```
```<li>``` に ```key``` 属性があることに**注意してください**。リスト内の各項目には、兄弟の中でそれを一意に識別するための文字列または数値を渡す必要があります。( ```key``` はデータベース上のIDなどが該当します)
リストの中身を追加・削除した場合、Reactは ```key``` でそれを識別します。
```App.tsx
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>
  );
}
```
### イベントに応答する
コンポーネントの中でイベントハンドラ関数を宣言することで、イベントに応答できます。
```jsx
function MyButton() {
 function handleClick() {
  alert('You clicked me!');
 }

 return (
    <button onClick={handleClick}>
     Click me
    </button>
 );
}
```
 ```onClick={handleClick}``` の末尾に**括弧がないことに注意して下さい!**
ここはイベントハンドラ関数を呼び出すのではなく、渡すだけです。ユーザがボタンをクリックしたときに、**React**がイベントハンドラを呼びます。
### 画面の更新
例えば、ボタンがクリックされた回数を数えて表示する画面があるとします。これを行うには、コンポーネントにstateを追加する必要があります。
まず、Reactから ```useState``` をインポートします。
```jsx
import { useState } from 'react';
```
これで、コンポーネント内にstate変数を宣言できます。
```jsx
function MyButton() {
  const [count, setCount] = useState(0);
  // ...
```
> ```useState``` からは2つのものが得られます。現在のstate(```count```)と、それを更新するための関数(```setCount```)です。名前は何でも構いませんが、慣習的には```[somthing, setSomething]```のように記述します。

> ボタンが初めて表示されるとき、```count``` は ```0``` になります。これは ```useState()``` に ```0``` を渡したからです。
stateを変更したいときは、```setCount()``` を呼び出し、新しい値を渡します。このボタンをクリックすると、カウンタが増加します。
```jsx
function MyButton() {
 const [count, setCount] = useState(0);

 function handleClick() {
    setCount(count + 1);
 }

 return (
    <button onClick={handleClick}>
     Clicked {count} times
    </button>
 );
}
```
> React は、再度コンポーネントの関数を呼び出します。今度は count が 1 になっています。次の呼び出しでは 2 になっています。次々と増えていきます。
同じコンポーネントを複数の場所でレンダーした場合、それぞれが独自の state を持ちます。それぞれのボタンを個別にクリックしてみてください：
```App.tsx
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``` というstateを「記憶」し、**他のボタンに影響を与えないようになっています。**
### フックの利用
```use```で始まる関数はフック(Hook)と呼ばれ、```useState``` はReactが提供する組み込みのフックです。([Reactの組み込みフック](https://ja.react.dev/reference/react))
既存のフックを組み合わせて独自のフックの作成も可能です。

:::note warn
ただ、フックには通常の関数より制限があります。コンポーネントのトップレベル(または他のフック内)でのみ呼び出すことができます。
:::
### コンポーネント間でデータを共有する
> 前述の例では、それぞれの ```MyButton``` が独立した ```count``` を持っており、ボタンがクリックされるたびにクリックされたボタンの ```count``` だけが変更されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779353/6e6f8589-974e-49e5-8528-116b765840a3.png)

> ただし、コンポーネント間でデータを共有し、常に一緒に更新したいということもよくあります。
両方の ```MyButton``` コンポーネントが同じ ```count``` を表示し、一緒に更新されるようにするには、状態を個々のボタンから「上に」移動して、それらすべてを含む最も近いコンポーネントに入れます。

>この例では、```MyApp``` がそれです：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779353/abe2cd9a-0997-4edd-866b-01b8f1f0d2d4.png)

このようにすると、どちらのボタンをクリックしても、```MyApp``` の ```count``` が更新され、連動して ```MyButton``` の両方のカウントが更新されます。
これらは下記のように表現します。

まず、```MyButton``` から ```MyApp``` にstateの移動を行います。
```jsx
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``` にstateを渡し、共有のクリックハンドラも一緒に渡します。
```jsx
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** として各ボタンに渡します。

最後に、```MyButton``` を変更して、親コンポーネントから渡された props を読み込むようにします。
```jsx
function MyButton({count, onClick}) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}
```
1. ボタンをクリックすると、```onClick``` ハンドラが発火します
1. 各ボタンの ```onClick``` プロパティは ```MyApp``` 内の ```handleClick``` 関数となっているので、その中のコードが実行されます
1. そのコードは ```setCount(count +1)``` を呼び出し、```count``` というstate変数をインクリメントします
1. 新しい ```count```の値が各ボタンに **props** として渡されるため、すべてのボタンに新しい値が表示されます

この手法は「stateのリフトアップ(持ち上げ)」と呼ばれています。リフトアップすることで、stateをコンポーネント間で共有できました！
```jsx
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>
  );
}

```

これで、Reactの基本が分かったと思います。
お疲れさまでした。


## ライセンス
本記事は、Reactの公式ドキュメント（[React 公式サイトへのリンク](https://react.dev/)）を参考に、Creative Commons Attribution 4.0 International License (CC BY 4.0) の下で公開されている情報に基づいて作成されています。