さあ、Reactの魔法を解き放て! 「あしながおじさん」に学ぶ、コンポーネント開発の極意
Blog Post
Aug 5, 2025

さあ、Reactの魔法を解き放て! 「あしながおじさん」に学ぶ、コンポーネント開発の極意

孤児院を卒業したジュディ。待ち受けていたのは、React開発の魔境だった!「Hello, World!」から始まる、propsとstateの壮絶な闘い。複雑化するコード、そして芽生える恋心… 彼女は、天才プログラマー“あしながおじさん”の助けを借り、幾多の困難を乗り越えることができるのか? 愛とコードが交錯する、感動と興奮の物語が、今、幕を開ける!

孤児院からの卒業式:初めてのReactコンポーネント

卒業式を終えたジュディは、期待に胸を膨らませ、大学の寮の小さな机に向かっていた。あしながおじさんからの手紙には、奨学金だけでなく、大学で学ぶReact開発のための資料とコード例も同封されていた。

「ふふっ、React…なんだか面白そう!」
ジュディは、資料を読み進めながら、初めての課題である「Hello, World!」コンポーネントの作成に取り組んだ。


function HelloJudy() {
  return (
    <h1>Hello, Judy!</h1>
  );
}

「簡単そうに見えたのに…全然動かないわ。」
ジュディは眉をひそめた。すると、すぐにあしながおじさんからメールが届いた。

「ジュディ、コンポーネントは、それ自身では表示されない。ReactDOM.renderを使って、HTMLの特定の要素にレンダリングする必要があるんだ。」
メールには、以下のようなコード例が添えられていた。


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HelloJudy />);

「なるほど!ルートっていうのね。植物みたいで面白い!」
ジュディは、早速コードを修正し、ブラウザをリロードした。

「わぁ!『Hello, Judy!』って表示された!」
ジュディは、喜びのあまり、寮のベッドに飛び込んだ。初めてのReactコンポーネントが動いた感動は、卒業式に劣らないくらい大きかった。

次の課題は、propsを使ったコンポーネントの作成だった。あしながおじさんから送られてきたコード例には、`Greeting`というコンポーネントがあった。


function Greeting(props) {
  return (
    <h1>Hello, {props.name}!</h1>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Greeting name="John" />);

「props…プロパティの略ね。これでコンポーネントに値を渡せるのね!」
ジュディは、`name`の値を"Jerusha"に変えてみた。


root.render(<Greeting name="Jerusha" />);

ブラウザをリロードすると、「Hello, Jerusha!」と表示された。
「すごい!まるで魔法みたい!」
ジュディは、Reactの奥深さにワクワクしていた。最後に、stateを使った、クリックでカウントアップするコンポーネントに挑戦した。


function ClickCounter() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<ClickCounter />);

「クリックするたびに数字が増える…!」
ジュディは、目を輝かせながら、何度もボタンをクリックした。Reactの魔法にすっかり魅了された彼女は、この技術をもっと深く学びたいという強い思いを抱きながら、眠りについた。

第1章の挿絵

状態管理の迷宮:props vs. stateのジレンマ

大学生活が始まり、寮の部屋はジュディのプログラミング書籍とコードで溢れかえっていた。Reactの課題は日に日に難しくなり、彼女は壁にぶつかっていた。

「もう!propsとstate、どっちを使えばいいの!?」
ジュディは、あしながおじさん、ジャーヴィスに助けを求めるメールを送った。


// Judy's Confused Component
function LibraryBookList(props) {
  const [books, setBooks] = React.useState(props.initialBooks);

  function handleBookReturn(book) {
    // ここでバグが発生!booksがうまく更新されない…
    setBooks(books.filter(b => b.id !== book.id));
  }

  return (
    <ul>
      {books.map(book => (
        <li key={book.id}>
          {book.title}
          <button onClick={() => handleBookReturn(book)}>Return</button>
        </li>
      ))}
    </ul>
  );
}

const initialBooks = [{ id: 1, title: "Little Women" }, { id: 2, title: "Anne of Green Gables" }];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<LibraryBookList initialBooks={initialBooks} />);

「ジャーヴィス、見て!`LibraryBookList`コンポーネントで、返却ボタンを押しても、本のリストがうまく更新されないの。`props.initialBooks`は変更しちゃいけないんでしょ?だからstateで管理してるんだけど…」

数時間後、ジャーヴィスから返信が届いた。

「ジュディ、それは`setBooks`の使い方の問題だね。`setBooks`は非同期で動作するから、以前の`books`の状態に依存した更新はうまくいかない。代わりに、更新関数を渡すんだ。」


// Jarvis's Improved Component
function handleBookReturn(book) {
  setBooks(prevBooks => prevBooks.filter(b => b.id !== book.id));
}

さらに、ジャーヴィスはuseReducerを使った高度な方法も教えてくれた。


// Jarvis's Advanced Component with useReducer
function bookReducer(state, action) {
  switch (action.type) {
    case 'return':
      return state.filter(book => book.id !== action.book.id);
    default:
      return state;
  }
}

function LibraryBookList(props) {
  const [books, dispatch] = React.useReducer(bookReducer, props.initialBooks);

  function handleBookReturn(book) {
    dispatch({ type: 'return', book: book });
  }

// ... (rest of the component remains the same)
}

「わぁ、`dispatch`!まるで図書館の本を仕分けるみたい!これで複雑な状態管理もできるのね!」
ジュディは、ジャーヴィスの丁寧な解説に感激し、早速コードを修正した。本のリストは、今度は完璧に動作した。

「ありがとう、ジャーヴィス!Reactの魔法が、ますます好きになったわ!」
ジュディは、次の課題、Context APIを使ったグローバル状態管理に、ワクワクしながら挑戦し始めた。

第2章の挿絵

恋愛とリファクタリング:複雑化するコードと複雑化する気持ち

大学生活は刺激に満ちていた。ジュディは図書館で、魅力的な青年ジャーヴィスに出会った。彼の博識で優しい物腰に、ジュディは次第に惹かれていった。

「ジャーヴィス、この前の`useReducer`、すごく役に立ったわ!ありがとう!」
「どういたしまして、ジュディ。ところで、最近はどんなコンポーネントを作っているんだい?」
「図書館の貸出システムをReactで再現しようとしてるの。でも…コードが複雑になってきて…」

ジュディは、複雑化した`LibrarySystem`コンポーネントのコードをジャーヴィスに見せた。


// Before refactoring: Complex LibrarySystem component
function LibrarySystem(props) {
  const [books, dispatch] = React.useReducer(bookReducer, props.initialBooks);
  const [members, setMembers] = React.useState(props.initialMembers);
  const [loans, setLoans] = React.useState([]);

  // ...たくさんの複雑な関数...

  return (
    <div>
      {/* ...複雑なJSX... */}
    </div>
  );
}

「見て、ジャーヴィス。`books`、`members`、`loans`…状態がいっぱい!それに、関数も複雑で、何をしているのか分からなくなってきたの…」
「確かに、少し複雑すぎるね。コンポーネントを分割して、リファクタリングしてみたらどうだい?」

ジュディは、あしながおじさんにも相談の手紙を書いた。現状のコードと、リファクタリング後のコードイメージ、そして、リファクタリングのベストプラクティスについての質問を綴った。

数日後、あしながおじさんから返信が届いた。リファクタリングの手順、そして、テスト駆動開発(TDD)の重要性についての丁寧な解説だった。

「なるほど!テストを先に書くのね!」
ジュディは、あしながおじさんのアドバイスに従い、`BookList`、`MemberList`、`LoanManager`といった小さなコンポーネントに分割し、それぞれのコンポーネントにテストを追加した。


// After refactoring: BookList component
function BookList(props) {
  const { books, dispatch } = props;

  return (
    <ul>
      {books.map(book => (
        <li key={book.id}>{book.title}</li>
      ))}
    </ul>
  );
}

// ... other refactored components (MemberList, LoanManager) ...

「わぁ!コードがすっきりした!まるで、散らかった部屋を片付けたみたい!」
ジュディは、リファクタリングの効果を実感した。そして、ジャーヴィスとの関係も、コードのように少しずつ整理されていくことを願っていた。

第3章の挿絵

大いなる贈り物:コンポーネント設計の真髄

卒業制作の締め切りが迫り、ジュディの部屋はまるで戦場だった。床には大量のコードを印刷した紙が散乱し、空になったコーヒーカップが積み重なっている。彼女は、大学図書館の蔵書管理システムをReactで開発するという、野心的なプロジェクトに挑戦していた。

「やっと完成…!」
疲労困憊のジュディは、椅子に深く腰掛けた。数週間、ほぼ不眠不休で作業した結果、ついにアプリケーションは完成したのだ。しかし、そのコードは、まるで長く伸びたジュディの髪の毛のように、絡まり合っていた。

その時、不意にジャーヴィスが部屋を訪れた。「ジュディ、大丈夫か?顔色が悪いぞ。」
「ジャーヴィス!ちょうどよかった。このコード、見てくれる?」


// Judy's Messy Component
function BookList(props) {
  // ...(hundreds of lines of code for searching, sorting, filtering, and displaying books)...
}

ジャーヴィスは、ジュディの書いたコードをしばらく眺め、静かに言った。「ジュディ、この`BookList`コンポーネントは、あまりにも多くの責任を負っている。検索、ソート、フィルタリング、表示…これらをそれぞれ独立したコンポーネントに分割してみたらどうだ?」


// Jarvis's Refactored Components
function SearchBar(props) { /* ... */ }
function SortOptions(props) { /* ... */ }
function FilterPanel(props) { /* ... */ }
function BookItem(props) { /* ... */ }

function BookList(props) {
  return (
    <>
      <SearchBar onSearch={props.onSearch} />
      <SortOptions onSort={props.onSort} />
      <FilterPanel onFilter={props.onFilter} />
      {props.books.map(book => <BookItem key={book.id} book={book} />)}
    </>
  );
}

「それから、この`BookItem`コンポーネントは、他のプロジェクトでも再利用できそうだ。コンポーネントライブラリにまとめて、公開してみたらどうだろう?」
ジュディは、ジャーヴィスの言葉にハッとした。まるで霧が晴れるように、コードの構造がクリアに見えてきた。

「ジャーヴィス…ありがとう。あなたのおかげで、卒業制作を完成させることができたわ。」
ジュディは、感謝の気持ちで胸がいっぱいになった。その時、ジャーヴィスは、真剣な眼差しでジュディを見つめた。

「ジュディ、実は…私は、君があしながおじさんと呼んでいる、ジャーヴィス・ペンデルトンだ。」
ジュディは、驚きで言葉を失った。まさか、自分の憧れの人が、ずっとそばにいたなんて…。

「えっ、じゃあ、あのTypeScriptの鬼のような課題も…?」
「ああ、あれは私が作った。すまない、少し厳しすぎたかな?」
二人は顔を見合わせて、笑い合った。卒業式の日、ジュディは、最優秀賞と、ジャーヴィスからのプロポーズを手にした。こうして、孤児院育ちの少女は、React開発者として、そしてジャーヴィスの妻として、新たな人生を歩み始めたのだった。めでたし、めでたし…?(TypeScriptの勉強は続く…)

第4章の挿絵
No items found.

Latest Posts

All Posts

Blog Post
Aug 10, 2025

橋の土台を築け! 「大工と鬼六」に学ぶ、レガシーシステムからの脱出 (技術的負債からの解放)

橋の土台を築け! 「大工と鬼六」に学ぶ、レガシーシステムからの脱出 (技術的負債からの解放)橋の土台を築け! 「大工と鬼六」に学ぶ、レガシーシステムからの脱出 (技術的負債からの解放)
Arrow Right Up
Arrow Right Up
Read Post
Read Post
Blog Post
Aug 10, 2025

扉を開けてはいけない! 「おおかみと七ひきのこやぎ」に学ぶ、多層防御とAPIセキュリティの重要性

扉を開けてはいけない! 「おおかみと七ひきのこやぎ」に学ぶ、多層防御とAPIセキュリティの重要性扉を開けてはいけない! 「おおかみと七ひきのこやぎ」に学ぶ、多層防御とAPIセキュリティの重要性
Arrow Right Up
Arrow Right Up
Read Post
Read Post
Blog Post
Aug 10, 2025

王様、何も着ていません!「裸の王様」に学ぶ、テストなしのシステムは危険です

王様、何も着ていません!「裸の王様」に学ぶ、テストなしのシステムは危険です王様、何も着ていません!「裸の王様」に学ぶ、テストなしのシステムは危険です
Arrow Right Up
Arrow Right Up
Read Post
Read Post
Blog Post
Jul 24, 2025

鏡よ鏡、一番美しいシステムは?「白雪姫」に学ぶ、スケーラブルなマイクロサービス設計

鏡よ鏡、一番美しいシステムは?「白雪姫」に学ぶ、スケーラブルなマイクロサービス設計鏡よ鏡、一番美しいシステムは?「白雪姫」に学ぶ、スケーラブルなマイクロサービス設計
Arrow Right Up
Arrow Right Up
Read Post
Read Post
Blog Post
Aug 6, 2025

五条大橋で、システムダウン寸前! 「弁慶と牛若丸」に学ぶ、マイクロサービス移行のススメ

五条大橋で、システムダウン寸前! 「弁慶と牛若丸」に学ぶ、マイクロサービス移行のススメ五条大橋で、システムダウン寸前! 「弁慶と牛若丸」に学ぶ、マイクロサービス移行のススメ
Arrow Right Up
Arrow Right Up
Read Post
Read Post
Blog Post
Aug 6, 2025

完璧なUIは鼻ほど長くはない! 「禅智内供」に学ぶ、シンプルUIの極意

完璧なUIは鼻ほど長くはない! 「禅智内供」に学ぶ、シンプルUIの極意完璧なUIは鼻ほど長くはない! 「禅智内供」に学ぶ、シンプルUIの極意
Arrow Right Up
Arrow Right Up
Read Post
Read Post