0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

このアドベントカレンダーのテーマ

この連載は、

技術初心者・非エンジニアの私が、ChatGPT を相棒にしながら
Next.js で Webアプリ(ブックマークアプリ)を 0 から作り切るまでの 24 日間の記録

です。

よくある

  • 「プロンプト投げたらツールが全部やってくれる」
  • 「AIにコード書かせてコピペして終わり」

みたいな話ではなく、

  • 手を動かすのはあくまで自分
  • ChatGPT は先生・相棒・レビュー係
  • わからないところを、その場で聞きながら進める

というスタイルで進めていきます。

「非エンジニアでも、ChatGPT をうまく使えば Webアプリ開発ってここまでできるのか」という実録にしたいです。

DAY1から読む↓

今日やること

Day5 のテーマは 「はじめてのフォームと、useStateで“入力した値”を扱ってみる」 です。

(useStateってなんだろう…)

Day4 で /bookmarks ページまでは作れたものの、そこで固まっています。何もできていない。体裁をなしているとは言えない。もはやページと呼んでいいかわからない。

今日は ChatGPT に教わりながら、

  • /bookmarks に URL入力フォームを置いてみる
  • 入力した文字を React の useState で持ってみる
  • 入力した内容をそのまま画面に表示してみる

ところまでを目標にしたらよさそうです。


Step 1. フォームはどう作っていけばよいのか?

Q:Next.js(React)で、URLを入力するフォームってどう書けばいいの?ちなみに私はHTMLのこともよくわからなから、HTMLなら~って書くのはやめてね。

ChatGPT の回答(要約):

了解!
HTML を前提にしないで、Next.js(React)だけの文脈で“URL入力フォーム”をゼロから説明するね。

初心者がいちばん混乱するポイントを全部避けつつ、
「これを書けばとりあえず動く」形に落とした 最小の例 でいくよ。


🎯 結論:まずはこれを書けば「URL入力フォーム」が動きます

"use client";

import { useState } from "react";

export default function BookmarkForm() {
  const [url, setUrl] = useState("");

  return (
    <div>
      <h2>URLを追加する</h2>

      <input
        type="text"
        value={url}
        onChange={(e) => setUrl(e.target.value)}
        placeholder="URLを入力してください"
      />

      <button onClick={() => alert(url)}>追加</button>
    </div>
  );
}

📌 このコードが何をしているのか(Reactだけで理解できるように説明)

use client が必要な理由

Next.js の app/ 配下はデフォルトで「サーバー側で動く」仕組み。

でも フォームは“画面側”で動く必要がある

だから、このページはクライアント側で動かすよ!という印になるのが:

"use client";

これを書くと、React の「動くUI」が使えるモードになる


useState で“入力値を覚える”

入力欄に文字を入れたら、Reactはその値をどこかに保存しておく必要がある。

その“保存場所”を作るのが useState

const [url, setUrl] = useState("");

意味は:

  • url → 今の入力値が入る場所
  • setUrl → 入力値を更新する関数

初心者向けにすごくシンプルに言うと…

「入力された文字を覚えておく箱を作る」のが useState。


<input> に「値を覚えてね」と教える

<input
  value={url}
  onChange={(e) => setUrl(e.target.value)}
/>

value={url}

→ 入力欄の中身は url(useStateの中身)と同じ にしますよ。

onChange={(e) => setUrl(e.target.value)}

→ ユーザーが入力したら、その文字を setUrl() で保存 しますよ。

これで「入力して → 状態が変わる → Reactが再描画」という基本の流れが成立する。


④ 最後のボタン

<button onClick={() => alert(url)}>追加</button>

ここではまだ DB も API もないので、
とりあえず押したら「入力した値」が見えるようにしてるだけ。

アプリとしては、

  • 将来:APIに送る
  • 今は:alertで動作確認

という仕組み。


🎉 初心者向けのめちゃシンプルまとめ

  • フォームは クライアントで動くので use client が必要

  • 入力された文字を保存するには useState を使う

  • <input>

    • value(今の値)
    • onChange(変わったときの処理)
      をセットすると動く
  • まずは入力したものを alert で確認すればOK


📌 じゃあこれをどこに置けばいいの?

次のようにするのが自然:

app/
  bookmarks/
    page.tsx
    BookmarkForm.tsx   ← ここに書く

そして page.tsx から読み込む:

import BookmarkForm from "./BookmarkForm";

export default function BookmarksPage() {
  return (
    <main>
      <h1>Bookmarks Page</h1>
      <BookmarkForm />
    </main>
  );
}

なるほど。
BookmarkForm.tsx を作成し、上記のコードを入れて、page.tsxも上書きする。

image.png

書き込める「フォーム」らしきものと追加ボタンのようなものができている!
ChatGPTも言っている通り、

とりあえず押したら「入力した値」が見えるようにしてるだけ。

ではあるのだけど。進歩進歩!!


Step 2. 入力した内容を画面に出すには?

入力している内容を、そのまま下の行に表示してみる

ところに進みたいと思います。

BookmarkForm.tsx を少しだけ書き換えます。

"use client";

import { useState } from "react";

export default function BookmarkForm() {
  const [url, setUrl] = useState("");

  return (
    <div>
      <h2>URLを追加する</h2>

      <input
        type="text"
        value={url}
        onChange={(e) => setUrl(e.target.value)}
        placeholder="URLを入力してください"
      />

      <button onClick={() => alert(url)}>追加</button>

      {/* 入力中の値をそのまま表示してみる */}
      <p>今入力しているURL:{url}</p>
    </div>
  );
}

<p>今入力しているURL:{url}</p> を足しただけ。

image.png

フォームに入力中の文字が下にでるようになった!

Q:今何が起きたの?

ChatGPTの回答(要約) めちゃくちゃ良い質問!! **「1行増やしただけに見えるのに、なんでこんなに“動くUI”になるの?」** ってところが、React の **本質** だから。

結論から言うと、
<p>今入力しているURL:{url}</p> を足したことで起きたのは──

🎯 起きたこと(超ざっくり)

“React が、state(url)が変わるたびに自動で画面を書き直すようになった”

ただそれだけ。
でもその「書き直し」の仕組みこそが React のコア機能。


🧠 実際にはこんな流れが起きている

① 入力欄に文字を打つ

ユーザーが例えば「https://aaa」と入力。

onChange が発動する

onChange={(e) => setUrl(e.target.value)}

この瞬間、
setUrl("https://aaa") が呼ばれて url が更新 される。

③ useState が「値が変わった」とReactに教える

Reactは内部で

“あ、url が変わったな。じゃあこのコンポーネントを描き直すか”

と判断する。

④ React が BookmarkForm 全体を丸ごと再レンダリング

つまり、
BookmarkForm の関数が もう一度実行される

↓ だから、この部分にも最新の値が入る:

<p>今入力しているURL:{url}</p>

⑤ 表示が最新状態に変わる

だから
入力欄に「h」と打てば {url} は「h」になり、
「ht」と打てば {url} は「ht」に変わる。

以上!


🎉 つまり、たった1行で“ライブ表示の仕組み”が完成した理由

理由はこれひとつ:
Reactが状態(state)の変化に応じて画面を自動で作り直すから。

あなたがやったのは:

  • state(url)を画面に表示するコードを書いた
  • onChange で state を更新するコードを書いた

React が勝手に

  • 値が変わったら、必要な部分を更新してくれる

という仕掛けまですべて面倒を見てくれる。

Step 3. 「追加ボタンを押した瞬間の値」も覚えてみる

入力中の値が表示できたので、次に必要なのは「追加ボタンを押した瞬間の値」のようです。

  • 入力しているとき → {url} がリアルタイムで更新される
  • 追加ボタンを押したとき → その時点のURLを別で覚えておきたい

という状態にしたい。

BookmarkForm.tsx を少し拡張する。

"use client";

import { useState } from "react";

export default function BookmarkForm() {
  const [url, setUrl] = useState("");
  const [submittedUrl, setSubmittedUrl] = useState("");

  const handleClick = () => {
    if (!url.trim()) return; // 空文字だったらスルー

    setSubmittedUrl(url); // ボタンを押した瞬間の値を覚える
    setUrl(""); // 入力欄をクリアする
  };

  return (
    <div>
      <h2>URLを追加する</h2>

      <input
        type="text"
        value={url}
        onChange={(e) => setUrl(e.target.value)}
        placeholder="URLを入力してください"
      />

      <button type="button" onClick={handleClick}>
        追加
      </button>

      <p>今入力しているURL:{url}</p>

      {submittedUrl && (
        <p>最後に追加したURL:{submittedUrl}</p>
      )}
    </div>
  );
}

image.png
こうなった!

Q:今のは何が起こった?

ChatGPTの回答(要約) めちゃくちゃ良い視点!!! これも **React という仕組みの大事なポイント** に触れてるので、 初心者が理解したら一気にレベルが上がる部分です。

結論から言うと、
あなたが書いたこのコード:

{submittedUrl && (
  <p>最後に追加したURL:{submittedUrl}</p>
)}

が追加されたことで起きているのは──


🎯 「値があるときだけ表示する」という“条件つきUI”が動くようになった

この一行(正確には3行)を追加したことで、

  • submittedUrl が 空文字のとき → 何も表示しない
  • submittedUrl に 値が入った瞬間 →

    が表示される

という「見たり消えたりするUI」が完成した。

これが React の条件レンダリング と呼ばれる仕組み。


🧠 実際にはこういう流れが起きている

① 初期状態:submittedUrl は空

const [submittedUrl, setSubmittedUrl] = useState("");

最初は ""(空文字)なので…

"" && (<p></p>)

これは JavaScript のルールで false と扱われる。

だから 何も表示されない

画面は静か。


② 「追加」を押すと setSubmittedUrl(url) が実行される

例えば https://example.com を追加したとすると…

submittedUrl は "https://example.com" になる。

これが truthy(=true扱い)


③ React が「状態が変わった!」と気づいて再描画する

BookmarkForm がもう一度実行され、

"https://example.com" && (<p>最後に追加したURL: https://example.com</p>)

これは true なので <p> の中身がそのまま画面に描かれる


④ 結果:「最後に追加したURL:…」が表示される


🎉 本質:React の “レンダリング = ただの if 文の世界”

条件レンダリングは実は「ただの if 文」と同じで、

  • true → 表示
  • false → 表示しない

というだけ。

でも React の凄いところは、

state が変わるたびに、勝手にこの条件式をもう一度評価して、UIを作り直してくれる

という点。

あなたがやったのはただの1行の追加なのに、

React が裏で

  • state の変化を検知して
  • コンポーネント全体を再計算して
  • 必要なところだけ差し替えて

…というめちゃくちゃ重い仕事を代わりにやってくれている。

なんかどんどん難しくなるな?ついていける気がしないぞ…
Reactが、とか、Next.jsが、とかじゃなくて、プログラミングの難しさに打ちひしがれている。

Day5 の締め:今日できたこと・明日やること

今日できたこと

  • /bookmarks にフォームを設置できた
  • useState を使って「入力中の値」を扱えるようになった
  • 入力した内容をそのまま画面に出すことができた
  • 追加ボタンを押したタイミングの値も別 state に保存できた
  • React が“状態の変化に反応してUIを描き直す”ことを体験できた

これ本当にあと20日で終わりそう??

明日やること(Day6)

Day6 では、今日の延長線上でもう一歩進めて、

  • URL を「1件」ではなく 配列で複数管理する
  • 配列を map で並べて「ブックマーク一覧っぽいもの」を表示する
  • 今後 API に送るための“準備運動”をしていく

いよいよ “ブックマークアプリ” の姿が少し見えてくる…のか⁉

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?