Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/01--setup.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
---
title: 環境構築
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/setup

---

import { Aside } from "@astrojs/starlight/components";
import { Tabs, TabItem } from '@astrojs/starlight/components';

### Node.js, npmのインストール

1. [Node.js](https://nodejs.org/)の公式サイトにアクセスします。
2. 画像のボタンをクリックすると、お使いのOSに適したLTS版インストールできるインストーラ(.pkg,.msi)がインストールされます。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2f057e55-54a7-4316-8c72-47b06026f254.png"></img>
<Tabs>
<TabItem label="Mac">
3. インストーラ(.pkg)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2b8d7d51-7c5d-47da-b0bc-29755c173753.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0186f00d-6dce-4cd5-8b3d-9f559b382259.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/0f6d798a-4be7-4b3a-8056-5949524efc15.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/f6a46775-7397-4230-b48b-cb1848002d2f.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/286805e8-d0d9-40c3-9a5a-120e5bd91016.png"></img>
</TabItem>

<TabItem label="Windows">
3. インストーラ(.msi)をクリックすると以下の画像のウィンドウが現れるので順番にインストール処理を行います。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/37453411-22ae-4d4a-ba73-d3e162ab6877.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/2807d2ca-fa6b-4b04-b0e1-bab3e0da080b.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ace86c97-5f8b-4981-8f52-23b6e96aedc0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/ce980dc2-14a1-498b-9cec-32e1c5f3ccc4.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/cf2f4f3a-0406-41ca-9a41-eedc9bb14d03.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/a4aafa1c-3ae8-41f7-9dd2-7639f881235d.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/60e67b2a-011c-4800-9435-08b6214f2dc5.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/c4953a86-52e6-4d06-8796-b8df25e5834e.png"></img>
</TabItem>

</Tabs>

4. インストール後、以下のコマンドでバージョンを確認できれば正常にインストールされています。表示されているバージョンが画像と同じでなくても大丈夫です。

```sh
node -v
npm -v
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/03004132-64ef-426c-9a53-54b4f59daa20.png
"></img>

### Reactプロジェクトのスタート

1. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。\
これにより、Viteを使用して新しいReactプロジェクトが作成されます。\
ここでは、プロジェクト名を`my-app`としていますが、任意の名前に変更できます。

```sh
npm create vite@latest my-app
```

<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/80d06c22-21b6-4a91-befe-226afb96a3bf.png"></img>

1. Reactを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/35e2167f-d785-48b5-bb6c-d170c284c888.png"></img>

2. JavaScriptを選択します。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/44e77390-48e8-44dc-bfff-936a0740dfb8.png"></img>

3. Doneが表示されたら完了です。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/12d514ad-5f29-47dd-b378-aaee65c89c5d.png"></img>

2. 作成したプロジェクトのディレクトリに移動します。
{/* タブ選択したい */}

```sh
cd my-app
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1bfb49c8-74bc-4062-be77-701fcdaa1206.png"></img>

3. 依存関係をインストールします。

```sh
npm install
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/197c208f-b7f6-4ba2-9a52-b693dea05562.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/5187855f-d6b1-4166-a7a8-9ccedf11558b.png"></img>

4. 実行すると、開発サーバーが立ち上がり、`➜ Local: http://localhost:5173/`の`http://http://localhost:⚪︎⚪︎⚪︎⚪︎`にブラウザでアクセスすると、Reactアプリが確認できます。
```sh
npm run dev
```
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/4627b189-7c69-4c36-b5a4-d86493943d90.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/1017ea65-362f-406c-9fc8-baf21beccab0.png"></img>
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/854fe47e-d7fb-4583-a114-3942f98da014.png"></img>

---
174 changes: 174 additions & 0 deletions src/content/docs/textbook/web/for-hackathons/02--react.mdx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
---
title: React
description: このチャプターでは、快適に XCode/VSCode で快適な C 言語を書くための秘訣を教えます。
slug: textbook/web/for-hackathons/react

---

import { Aside } from "@astrojs/starlight/components";

### Reactとは

**React** は、Facebook(現Meta)によって開発された **JavaScriptライブラリ** で、UIを効率的に構築するために使われます。

#### Reactの特徴

1. **コンポーネントベース**
- UIを小さな **コンポーネント** に分けて作成できる。
- それぞれのコンポーネントは独立しており、再利用が可能。
<img width="480" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/3530d227-197f-41c7-9043-d21a9d776d63.png"></img>

2. **宣言的UI**
- UIの状態を直接操作するのではなく、データの変化に応じて自動で更新される。

3. **仮想DOM(Virtual DOM)**
- リアルDOMを直接操作するのではなく、**仮想的なDOM** を使って差分のみを更新するため、高速に動作する。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/dc7ab56b-a356-4dd9-a860-5c1bebe46f61.png"></img>

4. **状態管理(State)**
- コンポーネントの状態(state)を管理し、動的なUIを実現できる。

5. **エコシステムが充実**
- `React Router`(ルーティング)や `Redux`(状態管理)など、多くのライブラリがある。

---

### 命令的 UI / 宣言的 UI

以下のようなものを実装するとする。
<img width="600" src="https://img.esa.io/uploads/production/attachments/19973/2025/03/26/148415/d0532148-5148-410a-a0f8-5020c6b86037.gif"></img>

#### 1. 命令的 UI(Imperative UI)
従来の JavaScript や jQuery のように、手続き的に UI を変更する方法。
**UIを更新する手順を細かく記述** しなければならず、コードが複雑になりやすい。

**例: jQueryを使った命令的UI**
```js
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
document.getElementById("message").innerText = "ボタンがクリックされました!";
});
```
上記のコードでは、ボタンがクリックされるたびに `document.getElementById()` を使って、DOMを直接操作している。

#### 2. 宣言的 UI(Declarative UI)
Reactのように、**データの変化に応じてUIを自動更新する方法**。
UIがどのように見えるべきかを **宣言的に記述** し、Reactが適切にレンダリングを行う。

**例: Reactを使った宣言的UI**
```jsx
import { useState } from 'react';

function App() {
const [message, setMessage] = useState("");

return (
<div>
<button onClick={() => setMessage("ボタンがクリックされました!")}>
クリック
</button>
<p>{message}</p>
</div>
);
}

export default App;
```
このコードでは、ボタンがクリックされると `message` の状態が変化し、それに応じて自動的に `<p>{message}</p>` の内容が更新される。

**Reactのポイント:**
- `useState` を使って **状態(state)** を管理
- UIの変更をReactに任せるため、**命令的なDOM操作が不要**

**Reactの宣言的UIのメリット:**
- コードがシンプルで可読性が高い
- UIの更新を意識せずに済むため、バグが減る
- 状態の変化に応じたUIの自動更新が可能

---

### コンポーネントのインポート

Reactの基本は **コンポーネント** であり、コンポーネントをインポートすることで再利用可能なUIを作成できる。

#### **1. コンポーネントの作成**
`MyComponent.js` という新しいファイルを作成し、Reactコンポーネントを定義する。

```jsx
function MyComponent() {
return <h1>これは MyComponent です!</h1>;
}

export default MyComponent;
```

#### **2. コンポーネントのインポート**
`App.js` で `MyComponent` をインポートして使用する。

```jsx
import MyComponent from './MyComponent';

function App() {
return (
<div>
<MyComponent />
</div>
);
}

export default App;
```

#### **3. デフォルトエクスポートと名前付きエクスポート**

**デフォルトエクスポート(default export)**
- 1つのファイルに1つのエクスポートを持つ。
- インポート時に任意の名前を使える。

```jsx
// MyComponent.js
export default function MyComponent() {
return <h1>デフォルトエクスポートのコンポーネント</h1>;
}
```
```jsx
// App.js
import MyComponent from './MyComponent';
```

**名前付きエクスポート(named export)**
- 1つのファイルに複数のエクスポートが可能。
- インポート時に **`{}` を使う必要がある**。

```jsx
// MyComponent.js
export function FirstComponent() {
return <h1>最初のコンポーネント</h1>;
}

export function SecondComponent() {
return <h1>2番目のコンポーネント</h1>;
}
```
```jsx
// App.js
import { FirstComponent, SecondComponent } from './MyComponent';

function App() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}

export default App;
```

**デフォルトエクスポートと名前付きエクスポートの違い**
| 項目 | デフォルトエクスポート | 名前付きエクスポート |
|------|------------------|------------------|
| エクスポートの数 | 1つのファイルに1つだけ | 1つのファイルに複数可能 |
| インポート時の記述 | `import 任意の名前 from './ファイル名'` | `import { 名前 } from './ファイル名'` |
| インポート名の変更 | **可能** | **不可(指定した名前と一致する必要あり)** |
Loading