Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
useEffect は使いたくないのですが、ではどうしたらいいですか
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
jsakamoto
April 08, 2026
Programming
110
1
Share
useEffect は使いたくないのですが、ではどうしたらいいですか
React .study vol.01@sapporo (
https://hokkaido-js.connpass.com/event/388202/
) での発表資料です。
jsakamoto
April 08, 2026
More Decks by jsakamoto
See All by jsakamoto
Google Chrome の開発者ツールで C# コードをデバッグできるって知ってました?
jsakamoto
0
52
開発したプレゼン用ツールが15年経っても誰も使ってくれない話
jsakamoto
0
88
UI コンポーネントカタログに MCP サーバー機能を追加する試み、そしてその結果
jsakamoto
1
120
いいね が燃料! 「自分のOSS」で1億ダウンロード突破の開発者が語る OSS 開発のリアル
jsakamoto
0
240
minify の効果を最大限に引き出す TypeScript コードを書く
jsakamoto
2
380
JavaScript 以外の言語によるフロントエンド Web 開発が既に実用段階である話
jsakamoto
0
2.9k
ベクトル化を使った意味検索を、簡単にアプリケーションに搭載できる時代になっていた件。
jsakamoto
2
400
CSR? SSR? C# で作る Web アプリフレームワーク Blazor のレンダリング方式を整理する
jsakamoto
0
1k
UI コンポーネントカタログ “Storybook” を、C# で SPA が作れる Blazor で再実装した話
jsakamoto
0
2.2k
Other Decks in Programming
See All in Programming
New "Type" system on PicoRuby
pocke
1
430
Old Dog, New Tricks: The Java 25 Reinvention - JNation
bazlur_rahman
0
140
ビジネスモデルから紐解く、AI+型駆動開発
hirokiomote
2
5.2k
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
170
Modding RubyKaigi for Myself
yui_knk
0
870
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
170
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
130
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
220
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
220
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
190
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
380
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
210
Being A Developer After 40
akosma
91
590k
It's Worth the Effort
3n
188
29k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
570
Large-scale JavaScript Application Architecture
addyosmani
515
110k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
190
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Everyday Curiosity
cassininazir
0
220
Transcript
useEffect は使いたくないのですが、 ではどうしたらいいですか React .study vol.01@sapporo
お題 GitHub の公開 REST API を 使って、指定のリポジトリの 貢献者を取得し、一覧表示す る React
アプリケーションを 作成します。
前提・制約 • 実用レベルのアプリケーションではなく、新人教育やブログ記事向けといった、 サンプルコードとしての作成 • React 以外の外部ライブラリは使用したくない • 単一のコンポーネントで完結させたい
かつてはこう書いていました
import "./App.css" ; import { useEffect, useState } from "react"
; import type { Contributor } from "./types/Contributor" ; function App() { const [ contributors , setContributors ] = useState <Contributor []>([]); useEffect (() => { ( async () => { const response = await fetch ( " http s :// api.github. com/ repos/jsakamoto/BlazingStory/contributors" ); const data : Contributor [] = await response . json (); setContributors ( data ); })(); }, []); return ( <section > <h1>Contributors </ h1> <div className ="contributors - grid" > { contributors . map(( contributor ) => ( <a key ={ contributor .login } href ={ contributor .html_url } target ="_blank" title ={ contributor .login } rel =" no <img src ={ contributor .avatar_url } alt ={ contributor .login } width ={ 40 } height ={ 40 } loading ="lazy" /> </ a> )) } </ div > </ section > ); } export default App;
初期データの fetch に useEffect は使いたくない • REST API の fetch
に useEffect は使うなとみんなが言ってる • いちどレンダリングが完了し DOM 要素の構築・マウントが済んでから、 初期データの fetch を開始することになる • 初期データの fetch なのに何故空データでのレンダリング完了を待たねばならぬのか • DOM 要素の構築・更新が完了したことを通知する Hook を、コンポーネント の初期データ取得に "流用" している違和感
React 19 からこう書いています
import "./App.css" ; import { Suspense, use, useState } from
"react" ; import type { Contributor } from "./types/Contributor" ; function App() { const [ contributors ] = useState ( async () => { const response = await fetch ( " http s :// api.github. com/ repos/jsakamoto/BlazingStory/contributors" ); const data : Contributor [] = await response . json (); return data ; }); return ( <section > <h1>Contributors </ h1> <div className ="contributors - grid" > <Suspense fallback ={ <p>Loading... </ p>} > <ContributorsList contributors ={ contributors } /> </ Suspense > </ div > </ section > ); } function ContributorsList ( props : { contributors : Promise <Contributor []> }) { const contributors = use ( props .contributors ); return ( <> { contributors . map(( contributor ) => ( <a key ={ contributor .login } href ={ contributor .html_url } target ="_blank" title ={ contributor .login } rel =" noope
use と Suspense で自然に書けるようになった • DOM の初回レンダリング完了を待つことなく、fetch を開始できる • コードの流れや意図もいい感じ
• useState に渡す初期値関数で Promise を返すところは「おぉ?」と思うかも? • でもいったん理解してしまえば、妥当と感じられると思う
しかし限界も • 単一コンポーネントに収まらなかったのが惜しい • use フック※は Suspense 配下のコンポーネントでしか使えない • なのでコンポーネント分割は不可避
• 「これはサンプルなので...」 がどこまで許されるか? • 実用レベルのアプリケーションでは、このような素朴な実装では、レースコンディション やネットワークウォーターフォールといった課題に対処できない ※2026/04/08 当日、会場で教えていただきましたが use はフックではなくて API でした 出典: https://react.dev/reference/react/use
SWR を使ってみます
import "./App.css" ; import useSWR from " swr " ;
import type { Contributor } from "./types/Contributor" ; function App() { const { data: contributors , isLoading } = useSWR ( " http s :// api.github. com/ repos/jsakamoto/BlazingStory/contributors" const response = await fetch ( url ); const data : Contributor [] = await response . json (); return data ; }); return ( <section > <h1>Contributors </ h1> <div className ="contributors - grid" > { isLoading ? ( <p>Loading... </ p> ) : ( contributors ?. map(( contributor ) => ( <a key ={ contributor .login } href ={ contributor .html_url } target ="_blank" title ={ contributor .login } rel =" n <img src ={ contributor .avatar_url } alt ={ contributor .login } width ={ 40 } height ={ 40 } loading ="lazy" /> </ a> )) ) } </ div > </ section > ); } export default App;
単一コンポーネントに収まった • かつ、実用レベルのアプリケーション実装においても流用できる • 公式による "データ取得にはライブラリを使え" の推奨に従った形 • ただし、SWR という外部ライブラリに依存してしまった
• サンプルコードとしての中立性が失われる • なぜ TanStack Query や React Router を採用しなかったのか、みたいなツッコミも
まとめ
脱 useEffect には成功しましたが... • 実用レベルでは、外部ライブラリで非同期データを取得すべき、ですね? • React 18 以前でも OK
• ただしどのライブラリに依存するべきか悩む必要が発生 • React 19 の use フック※を使えばかなり自然に書ける • ただし単一コンポーネントには収まらない • 実用レベルでは問題ある点を「サンプルだから...」で押し通せるか? • サンプルコードという文脈では、どちらの道を選ぶか悩ましい ※2026/04/08 当日、会場で教えていただきましたが use はフックではなくて API でした 出典: https://react.dev/reference/react/use
Learn, Practice, Share.