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
jsakamoto
April 08, 2026
Programming
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
WebMCPを試してみました
jsakamoto
0
26
VRT in Blazor App Dev - .NET Lab 2026 Jul LT
jsakamoto
0
62
Google Chrome の開発者ツールで C# コードをデバッグできるって知ってました?
jsakamoto
1
86
開発したプレゼン用ツールが15年経っても誰も使ってくれない話
jsakamoto
0
100
UI コンポーネントカタログに MCP サーバー機能を追加する試み、そしてその結果
jsakamoto
1
130
いいね が燃料! 「自分のOSS」で1億ダウンロード突破の開発者が語る OSS 開発のリアル
jsakamoto
0
260
minify の効果を最大限に引き出す TypeScript コードを書く
jsakamoto
2
390
JavaScript 以外の言語によるフロントエンド Web 開発が既に実用段階である話
jsakamoto
0
2.9k
ベクトル化を使った意味検索を、簡単にアプリケーションに搭載できる時代になっていた件。
jsakamoto
2
420
Other Decks in Programming
See All in Programming
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
170
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
230
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
130
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
460
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
110
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
330
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
190
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.5k
Featured
See All Featured
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
190
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Unsuck your backbone
ammeep
672
58k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
ラッコキーワード サービス紹介資料
rakko
1
3.9M
How to Ace a Technical Interview
jacobian
281
24k
Prompt Engineering for Job Search
mfonobong
0
380
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
BBQ
matthewcrist
89
10k
HDC tutorial
michielstock
2
750
Designing for Performance
lara
611
70k
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.