どうも、マイクです。おはようございます。
2025年12月17日、水曜日の朝7時をまわりました。ここからの時間は「zenncast」、きょうもZennで話題になっているトレンド記事をゆるっと、でも中身はみっちりご紹介していきます。通勤・通学の支度をしながら、あるいはまだ布団の中でぬくぬくしながら、耳だけ貸してもらえたらうれしいです。
さて、きょうはお便り紹介はお休みで、その分ガッツリ記事を取り上げていきます。
きょうご紹介する記事は全部で5本。フロントエンドからGit運用、状態管理、Rustの形式検証、そしてラーメンチェーンのファンアプリまで、技術と愛が詰まったラインナップになっています。
まず1本目。
タイトルは「React の状態管理の歴史と、最新 API に込められた React の思想」。
Reactを書いていると「状態管理どうする問題」、一度は考えますよね。この記事は、その迷いを「歴史」と「思想」からほどいてくれる内容です。
Reactにおける状態って、「時間とともに変化して、UIに影響を与える値」なんだと。UIはあくまで `f(state)`、つまり状態の“結果”である、という考えが一貫してるんだよ、というところから話が始まります。
初期の頃、React本体は「コンポーネント内部の状態」は強いけれど、「アプリ全体で状態をどう共有するか」「どう永続化するか」は弱かった。そのスキマを埋める形でFluxやReduxが登場して、一方向データフローと単一ストアで「予測可能な状態管理」を打ち立てる。でも、実務で使うと“儀式っぽくて重い”という悩みも出てきた。
そこに出てくるのがRecoil。状態をatomとselectorに分けて、依存グラフで派生状態を扱える“Reactっぽい”アーキテクチャを提示します。さらにZustandは「Just JavaScript」を掲げて、軽くて柔軟なストアとして人気に。
で、React 18以降、Concurrent Renderingが本格化してくると、「外部ストアとReactの世界がズレて表示がおかしくなる」問題が表面化します。そこで公式が用意したのが `useSyncExternalStore`。これが「外部にある状態のスナップショットを、Reactが正しく同期して描画する」ための低レイヤAPIなんですね。
記事の肝は、「状態はアプリやサーバー側にあって、Reactはその投影を描画しているだけ」という哲学を確認したうえで、ライブラリ選定の軸を「どう同期するか」に置こう、というメッセージ。Redux vs Recoil vs Zustandみたいな“宗教戦争”ではなく、“Reactの思想と矛盾しないか?”を物差しにしよう、と。状態管理で悩んでるチームのディスカッション材料にとてもよさそうな一本です。
。 。 。 。
続いて2本目。
タイトルは「もうgit stashは卒業!git worktree + wtp で実現する、ストレスゼロの並行開発」。
「作業中のブランチがあるのに、いきなり緊急バグが飛んできた…!とりあえず `git stash` して…あれ、どのstashがどの作業だっけ?」ってなったこと、ありませんか?この記事は、そんな“stash地獄”から抜け出すための運用を提案してくれます。
キーワードは「git worktree」と、そのラッパーツール「wtp」。
git worktreeは、1つのリポジトリから複数の作業ディレクトリを生やして、ブランチごとに“物理的に別フォルダ”を持てる仕組みです。コンテキストスイッチしたいときは、別ディレクトリに移動するだけ。コードも設定もごっちゃにならない。
とはいえ素のgit worktreeは、コマンドが長くて覚えにくいし、作ったディレクトリの中で毎回 `.env` コピーしたり `npm install` したり、後片付け(削除)も二度手間になりがち。
そこで登場するのがCLIツール「wtp」。
これを使うと、
・worktreeの作成、移動、削除が短いコマンド一発
・`.wtp.yml` に「post_create」フックを書いておけば、`.env` コピーや依存インストールを自動化
・ブランチとディレクトリの対応関係も整理して管理
といった感じで、“ゼロセットアップで新しい作業環境がポンと出てくる”体験になります。
さらに面白いのが、「worktreeごとにAIコーディングアシスタントのコンテキストも分ける」という発想。タスクA用のディレクトリではAの議論だけ、タスクBではBだけ、というふうにAI側の記憶もきれいに分離できる。これによって、頭の切り替えも、ツールのコンテキストも全部 “物理的に”分けてしまおう、という提案なんですね。
「stashに名前をメモってる」「ローカルがブランチだらけでカオス」という人は、次の一歩として試してみる価値ありそうです。
。 。 。 。
3本目。
タイトルは「z-index 地獄を避ける方法」。
フロントエンドやってると、z-indexってつい“数字勝負”になりがちですよね。`z-index: 9999` とか、謎のマジックナンバーが生まれてしまうやつ。この記事は、その前に「ブラウザがどうやって重なり順を決めているのか」をちゃんと押さえよう、という内容です。
まずは、z-indexを指定しないときの基本ルール。
同じStacking Contextの中では、
・positionありの要素が上に来る
・同じレイアウト方法同士なら、DOMツリーの“後ろに書かれたもの”が上に来る
・z-indexは、その順序を“上書きする”ためのもの
といった原則がある。
そしてキーワードが「Stacking Context」。これは、重なり順の計算が“グループごとに完結する箱”みたいなもので、この箱が変わると、いくらz-indexが高くても“別の箱の中身には勝てない”。
なので、「1ページをまるっと1つのStacking Contextでどうにかしよう」とするからz-index地獄になるのであって、「必要な単位ごとにコンテキストを分ける」と、考える範囲がぐっと狭まって楽になるよ、という話なんですね。
記事では実例として、Page Builder的なUIをどう設計したかが紹介されます。
・ヘッダーなどの固定UI
・ページプレビュー
・プレビュー上のハイライト+編集メニュー
こういった要素を、Stacking Contextごとに整理し直して、できるだけDOM順とpositionだけで重なりを表現。どうしても必要なところだけ、最小限のz-indexを使う構成にしています。
さらに、「プレビュー内の要素をハイライトする」仕組みも丁寧に解説。DOMからrectを取得して、それに合わせてハイライトの位置を動かす。サイズ変化はResizeObserverで拾って、スクロールの扱いも工夫して同期を取っている。
まとめとして、「レイアウト種別・DOM順・Stacking Contextを理解したうえで、構造設計からz-index地獄を避けよう」という、設計レベルの話になっているのがポイント。z-indexの数字で殴り合っているチームに、ぜひ一度共有したい記事です。
。 。 。 。
4本目。
タイトルは「山岡家Map(非公式)を作った話」。
ここから一気に“推し活”寄りの話になります。筆者は長年のラーメン山岡家ファンで、「自分の得意分野でチェーンを応援したい!」という思いから、全国の山岡家を地図上で眺められる「山岡家Map(非公式)」を作って公開しています。
通常店舗、煮干し系、味噌専門、そして「餃子の山岡家」という4業態を、それぞれ別アイコン・別レイヤで表示。しかもPWA対応で、スマホのホーム画面からアプリっぽく使えるようになっています。
技術的にはかなり本格的で、まずは公式サイトに事前許可をきちっと取ったうえで、Playwrightを使って店舗ページをスクレイピング。
・店舗名
・住所、電話番号
・営業時間
・駐車場・座席数
・シャワーの有無
・緯度経度
といった情報を取得していきます。位置情報はDMS形式で書かれているので、geopyでDD形式に変換し、pandasでカラム名を英語化して整理。そのデータから、店舗タイプごとにGeoJSONを生成していく、という流れです。
フロントエンド側は、Amazon Location ServiceとMapLibre GL JSを組み合わせて実装。カスタムアイコンのレイヤや、店舗をタップしたときのポップアップ、レイヤのON/OFF切り替えなんかも作り込みつつ、Amplify Gen2でホスティングまで全部まとめています。
地図として眺めると、「最北は稚内」「東京は密集してて、四国はまっさら」「餃子の山岡家は全国で1店舗のみ」といった出店パターンも見えてきて、ファン的にも地理オタク的にも楽しい。近場や旅行先で「ここから一番近い山岡家どこ?」と調べる用途にもバッチリです。
推しチェーンや好きなコンテンツを、自分のスキルで可視化して応援する、その姿勢も含めてすごく良いプロジェクトでした。
。 。 。 。
そしてきょう最後、5本目。
タイトルは「kaniで数学的に証明するRust標準ライブラリの安全性」。
これはAWS re:Invent 2025のChalk talkで紹介された内容をベースに、Amazon製OSSの「kani」というツールで、Rust標準ライブラリの安全性を“数学的に”証明していく話です。Rustといえば「安全性」が売りですが、標準ライブラリの中には、どうしても `unsafe` な実装が必要な箇所があって、実際に過去にはCVEも出ています。そこで登場するのが形式検証、というわけですね。
kaniは、Rustのコードを記号実行して、
・`assume` と `assert`
・`requires` / `ensures` といったContract
をSATソルバーに投げて、「どんな入力に対してもバグが起きないか」を網羅的にチェックしてくれます。オーバーフロー、未定義動作、ポインタの不正参照などを、人間のテストでは到底カバーしきれないパターンまで潰していける。
記事では例として、`NonZero<u8>` 型の `unchecked_add` というunsafeメソッドを取り上げます。「ゼロではない値に対して、オーバーフローしない範囲で足し算をしたとき、結果も必ずゼロではない」という性質を、kaniでどう表現し、どう証明していくのか。その手順と検証ログが丁寧に紹介されています。
さらに面白いのが、LLMを組み合わせた取り組み。関数の実装をもとに、LLMに「この関数のContract(前提条件と保証したいこと)を自動生成させる」というアイデアです。人間が1個1個仕様を書き下すとコストが高いところを、AIに叩き台を作らせて、そこから人間がレビューすることで、検証のスピードアップを狙っている。
最後は、GitHub上で公開されている検証課題へのリンクや、今後のツール解説・LLM活用の続報への期待で締められていて、「安全性を“証明する”世界」がかなり現実的になってきているんだな、というワクワクを感じる記事でした。
。 。 。 。
そろそろお別れの時間です。
きょうのzenncastでは、
・Reactの歴史を振り返りながら、「状態は外部にあってUIはその投影」という思想を整理してくれた、Reactの状態管理の記事。
・`git stash` から卒業して、git worktree+wtpでストレスフリーな並行開発をしよう、という運用ノウハウ。
・Stacking ContextとDOM順序を理解して、z-index地獄を設計から避けるフロントエンドの記事。
・ラーメン山岡家への愛から生まれた、スクレイピング〜地図表示までフルスタックな「山岡家Map(非公式)」。
・Amazonの「kani」でRust標準ライブラリのunsafeを数学的に検証しよう、という最前線の形式検証の話。
この5本をご紹介しました。気になった記事があれば、詳しい内容や元の記事へのリンクはショーノートにまとめておきますので、あとでゆっくりチェックしてみてください。
この番組「zenncast」では、放送の感想や、「こんなテーマを扱ってほしい」「この技術記事がおもしろかった」など、みなさんからのメッセージもお待ちしています。あなたの一通が、次回のトピックになるかもしれません。
それでは、きょうも良い一日をお過ごしください。
ここまでのお相手はマイクでした。また次回、お耳にかかりましょう。