$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
useSyncExternalStoreを使いまくる
Search
TOMIKAWA Sotaro
December 10, 2024
Programming
6
6.2k
useSyncExternalStoreを使いまくる
TOMIKAWA Sotaro
December 10, 2024
Tweet
Share
More Decks by TOMIKAWA Sotaro
See All by TOMIKAWA Sotaro
Atomics APIを知る / Understanding Atomics API
ssssota
1
570
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
15
49k
Web技術を最大限活用してRAW画像を現像する / Developing RAW Images on the Web
ssssota
2
2.5k
漸進。
ssssota
0
3.2k
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
ssssota
1
3.1k
React CompilerとFine Grained Reactivityと宣言的UIのこれから / The next chapter of declarative UI
ssssota
8
5.7k
新しいAPI createRawSnippet触ってみた / What is the createRawSnippet?
ssssota
2
250
脱法Svelte / Evasion of svelte rules
ssssota
1
270
Documentation testsの恩恵 / Documentation testing benefits
ssssota
2
1.1k
Other Decks in Programming
See All in Programming
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
130
20251212 AI 時代的 Legacy Code 營救術 2025 WebConf
mouson
0
130
WebRTC と Rust と8K 60fps
tnoho
2
2k
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
170
関数実行の裏側では何が起きているのか?
minop1205
1
690
DSPy Meetup Tokyo #1 - はじめてのDSPy
masahiro_nishimi
1
160
「コードは上から下へ読むのが一番」と思った時に、思い出してほしい話
panda728
PRO
38
26k
How Software Deployment tools have changed in the past 20 years
geshan
0
29k
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
320
ゲームの物理 剛体編
fadis
0
340
AIエージェントを活かすPM術 AI駆動開発の現場から
gyuta
0
400
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
6
3.2k
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
37
3.5k
For a Future-Friendly Web
brad_frost
180
10k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Speed Design
sergeychernyshev
33
1.4k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
Making Projects Easy
brettharned
120
6.5k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Facilitating Awesome Meetings
lara
57
6.7k
Typedesign – Prime Four
hannesfritz
42
2.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Transcript
useSyncExternalStoreを 使いまくる 株式会社ユーザベース×株式会社ZOZO×株式会社PR TIMES 3社合同フロントエンド勉強会 株式会社ZOZO ブランドソリューション開発本部WEARフロントエンド部Webブロック 冨川宗太郎 Copyright ©
ZOZO, Inc. 1
© ZOZO, Inc. 株式会社ZOZO ブランドソリューション開発本部 WEARフロントエンド部Webブロック 冨川 宗太郎 2022年 ZOZOに新卒入社。
WEARのWeb開発に従事。テックリードを務める。 趣味はOSSとカメラ。 2
© ZOZO, Inc. https://wear.jp/ 3 • あなたの「似合う」が探せるファッションコーディネートアプリ • 1,700万ダウンロード突破、コーディネート投稿総数は1,400万 件以上(2024年9月末時点)
• コーディネートや最新トレンド、メイクなど豊富なファッション 情報をチェック • AIを活用したファッションジャンル診断や、フルメイクをARで試 せる「WEARお試しメイク」を提供 • コーディネート着用アイテムを公式サイトで購入可能 • WEAR公認の人気ユーザーをWEARISTAと認定。モデル・タレン ト・デザイナー・インフルエンサーといった各界著名人も参加
© ZOZO, Inc. 4 WEAR Webの今と役割 WEAR (wear.jp) は絶賛リプレイス中! VBScriptという古の言語で一部稼働しており、
Next.js(Pages Router) / React環境に移行中。 服でお困りのユーザーにGoogleなどの検索で辿り着いてもらい、 多くのユーザーにファッションの参考にしてもらうのが使命。 リプレイスだけではなく日々改善を積み重ねていく必要がある... 今日はそんな前提の話。
© ZOZO, Inc. 5 改善のために ひと口に改善といっても守らなければいけないラインがある。 • リプレイス前環境の制約 ◦ 認証・認可
• リプレイスに基づく制約 ◦ パスの最適化 • 各種キャッシュ • etc... 他所への影響を最小限に抑えながら素早く改善したい。 できればABテストで影響も見ながら。
© ZOZO, Inc. 6 方針 Next.jsのMiddlewareでCookie(非HttpOnly) にABテスト設定を注入 クライアントサイドJSでCookieを読んで表示制御 • HTTPメッセージをほとんど汚染せず(Set-Cookieのみ)
• キャッシュの邪魔もせず • ユーザー別のUIが表示できる
© ZOZO, Inc. 7 middleware export const middleware: NextMiddleware =
(req) => { const res = NextResponse.next(); res.cookies.set( COOKIE_NAME, random(PATTERN_A, PATTERN_B), ); return res; }; ヨシ。
© ZOZO, Inc. 8 コンポーネント export const Component: React.FC =
() => { const pattern = getCookie(COOKIE_NAME); if (pattern === PATTERN_A) return ...; // PATTERN_B return ...; }; SSRできない。(getCookieはクライアントサイドでのみ使えるものとする)
© ZOZO, Inc. 9 SSR対応 export const Component: React.FC =
() => { const pattern = typeof window !== undefined ? getCookie(COOKIE_NAME) : PATTERN_B; if (pattern === PATTERN_A) return ...; // PATTERN_B return ...; }; SSRするとHydration Errorが発生する。
© ZOZO, Inc. 10 useEffectでマウント後に取得 export const Component: React.FC =
() => { const [pattern, setPattern] = useState(PATTERN_B); useEffect(() => { setPattern(getCookie(COOKIE_NAME)); }, []); if (pattern === PATTERN_A) return ...; // PATTERN_B return ...; }; クライアントサイドレンダリングでも無駄な再描画が発生する。
© ZOZO, Inc. export const Component: React.FC = () =>
{ const pattern = useSyncExternalStore( () => () => {}, () => getCookie(COOKIE_NAME), () => PATTERN_B, ); if (pattern === PATTERN_A) return ...; // PATTERN_B return ...; }; 11 useSyncExternalStore
© ZOZO, Inc. 12 useSyncExternalStoreとは 公式ドキュメント(https://ja.react.dev/reference/react/useSyncExternalStore) useSyncExternalStore は、外部ストアへの サブスクライブを可能にする React
のフックです。 外部ストア?サブスクライブ?
© ZOZO, Inc. 13 useSyncExternalStoreとは 基本は「第2引数の返り値を返す」フック。 const value = useSyncExternalStore(
() => () => {}, () => "#zup_frontend", ); return value; // "#zup_frontend" ... なにがうれしいんだっけ?
© ZOZO, Inc. 14 唯一無二 第三引数 SSR時とHydration時は、第2引数の代わりに第3引数に渡した関数が実行される const value =
useSyncExternalStore( () => () => {}, () => "Now CSR (window/document are available)", () => "Now SSR or Hydrating", ); ブラウザ側でしか使えない関数やリソースを必要な時だけ利用できる。 Hydration Errorの回避にも使える。
© ZOZO, Inc. 15 () => () => {} 第1引数のコレ↑はなに?
外部ストアへのサブスクライブ をするための関数。 サブスクライブ(=購読≃同期)をする必要がないときは () => () => {} この形になる。
© ZOZO, Inc. 16 第1引数 第1引数をもう少し細かく確認する。リアルな例を見てみる。 createdAtをHydrationに配慮しながらフォーマットする例: const formatted =
useSyncExternalStore( (callback) => { const id = setInterval(callback, 60 * 1000); return () => clearInterval(id); }, () => formatTimeDelta(new Date(createdAt)); () => new Date(createdAt).toISOString(); );
© ZOZO, Inc. 17 第1引数 Reactの外にある何か(window,document,store,etc...)と同期したいときに利用。 const subscribe = (callback)
=> { // 値などが変化したらcallbackを呼ぶ const unsubscribe = () => { // コンポーネントが破棄されるときに呼ばれる }; return unsubscribe; }; callbackが呼ばれると、第二引数に渡した関数が再評価されて値が変化する。
© ZOZO, Inc. 18 使い方いろいろ • Hydration Error回避 • mediaQuery
(window.matchMedia) • ResizeObserver • localStorage • navigator.onLine • フレームワークを跨いだsignal/store同期 • 独自store実装 • navigator.canShare • クライアント限定fetch処理 • etc...
© ZOZO, Inc. 19 useSyncExternalStore ロジックを分離しやすいインターフェース。 クライアントサイドロジックとの親和性が非常に高い。 まずは自作storeからはじめてみよう!
None