Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Shift-from-React-to-Vue
Search
Moriyama Nagi
November 01, 2024
Technology
5.4k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Shift-from-React-to-Vue
Moriyama Nagi
November 01, 2024
More Decks by Moriyama Nagi
See All by Moriyama Nagi
AIの非決定性を吸収する設計: youtrust_09_19
calm1205
1
530
Other Decks in Technology
See All in Technology
アプリをもっと"iOSアプリっぽく"する小さな工夫 / Small Touches That Make Your App Feel More Like an iOS App
matsuji
1
190
20260906 「AWS運用入門」著者が教える、運用業務への生成AI活用入門
masaruogura
0
260
From Vanilla Kubernetes to a Batteries-Included Platform: Developer Experience at 1,300+ Clusters
yosshi_
0
670
あるけみー式LTスライド作成術
alchemy1115
1
150
[DroidKaigi 2026] Making UI specifications visible: Android UI development in the AI agent era supported by Compose Screenshot Testing and galleries
syarihu
0
610
ASTを使って影響範囲を特定する
nealle
0
140
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
430
作り直せるコードは迅速に 作り直せないDBは慎重に - AI時代のプロダクトエンジニアが「判断の不可逆性」で開発速度を変える話
kinosuke01
0
280
振り返りこそエンジニアの本領
negima
0
360
Screen Lens - 今見てる画面を翻訳する
komagata
0
210
2026-09-11 【Snowflake World Tour Tokyo 2026】Snowflakeを起点に、AI Agentが自律稼働し続ける未来へ / Driving AI Agents with Snowflake
civitaspo
0
260
AIで実装は速くなった。なのにプロダクトは速くならない。職能の壁を越えて価値のフローを設計する
nwiizo
7
7.6k
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
230
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
880
A Tale of Four Properties
chriscoyier
163
24k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
330
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
450
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
270
Transcript
©MNTSQ, Ltd. 2024/11/01 ReactからVueへの転向: 思考の変化とアプローチの違い 森山 凪
©MNTSQ, Ltd. 2 自己紹介
©MNTSQ, Ltd. 3 3年 1年 3ヶ月(趣味) 森山 凪 モリヤマ ナギ
MNTSQ株式会社 フロントエンド 4年目
©MNTSQ, Ltd. 4 過去やってきたこと
©MNTSQ, Ltd. 5 前職はHR領域のSaaSをマイクロサービスアーキテクチャで開発 自己紹介 New HR SaaS Fix
©MNTSQ, Ltd. 6 新サービスの開発方針 自己紹介 GraphQLからTypeScriptの型を自動生成 Storybook x ChromaticでのUIの差分検知 Gherkin記法でユースケースをGit管理
Cypress x CucumberでE2E API、UI、ユースケース 変われば悲鳴をあげるFE
©MNTSQ, Ltd. 7 マイクロサービスそれぞれを見てみると、、、 自己紹介 HR SaaS あれ、、 各サービスで微妙にデザインに違うな
©MNTSQ, Ltd. 8 自己紹介 HR SaaS HR SaaS Private npm
package UIコンポーネントライブラリの作成
©MNTSQ, Ltd. 9 ReactからVueへの転向: 思考の変化とアプローチの違い
©MNTSQ, Ltd. 10 目次 1. ライフサイクル表現の変化 2. 構文の変化 3. まとめ
©MNTSQ, Ltd. 11 目次 1. ライフサイクル表現の変化 2. 構文の変化 3. まとめ
©MNTSQ, Ltd. 12 ライフサイクル表現の変化
©MNTSQ, Ltd. 13 ライフサイクルの変化 React Vue useEffect lifecycle hook
©MNTSQ, Ltd. 14 ライフサイクルの変化 React Vue useEffect lifecycle hook
©MNTSQ, Ltd. 15 ライフサイクルの変化 React Vue useEffect() 1. update 2.
mount 3. unMount =
©MNTSQ, Ltd. 16 ライフサイクルの変化 useEffect() update mount unMount
©MNTSQ, Ltd. 17 どうやってuseEffectで 3つのlifecycleを表現しているのか?
©MNTSQ, Ltd. 18 ライフサイクルの変化 useEffectのlifecycle表現 const Component = () =>
{ useEffect( ()=>{ }, [ ] ) } 1. onMount 2. onUpdate 3. onUnmount
©MNTSQ, Ltd. 19 ライフサイクルの変化 const Component = () => {
useEffect(()=>{ // 1回目はonMount },[]) } 1. onMount ◦ Component()実行でuseEffect()も呼ばれる。 ◦ useEffectの初回実行がmount 2. onUpdate 3. onUnmount useEffectのlifecycle表現
©MNTSQ, Ltd. 20 ライフサイクルの変化 1. onMount ◦ Component()実行でuseEffect()も呼ばれる。 ◦ useEffectの初回実行がmount。
2. onUpdate ◦ useEffectの第2引数が変化する度に useEffectが再発火する。 ◦ state1, state2どちらが変わっても発火。 3. onUnmount const Component = () => { const [state1,] = useState() const [state2,] = useState() useEffect(()=>{ // 1回目はonMount // 2回目以降はonUpdate },[state1, state2]) // 依存配列 } useEffectのlifecycle表現
©MNTSQ, Ltd. 21 ライフサイクルの変化 1. onMount ◦ Component()実行でuseEffect()も呼ばれる。 ◦ useEffectの初回実行がmount。
2. onUpdate ◦ useEffectの第2引数が変化する度に useEffectが再発火する。 ◦ state1, state2どちらが変わっても発火。 3. onUnmount ◦ useEffectの第1引数の返り値がunmount。 const Component = () => { const [state1,] = useState() const [state2,] = useState() useEffect(()=>{ // 1回目はonMount // 2回目以降はonUpdate return () => {} // onUnmount },[state1, state2]) } useEffectのlifecycle表現
©MNTSQ, Ltd. 22 ライフサイクルの変化 なるほど!!
©MNTSQ, Ltd. 23 ライフサイクルの変化 useEffectはムズい
©MNTSQ, Ltd. 24 ライフサイクルの変化 useEffectムズい lifecycleを理解している人でないと (useEffectは)難しい
©MNTSQ, Ltd. 25 useEffectのなんのため?
©MNTSQ, Ltd. 26 ライフサイクルの変化 useEffectの恩恵は何?
©MNTSQ, Ltd. 27 ライフサイクルの変化 useEffectの恩恵は何? → 機能的な凝集性が高い
©MNTSQ, Ltd. 28 ライフサイクルの変化 useEffectの恩恵は何? → 機能的な凝集性が高い const Component =
() => { // API コール useEffect(()=> { const response = apiCall(payload) setResponse(response) }, [payload]) // タイマー処理 useEffect(()=>{ const timerId = setInterval(() => { // tick process }, 1000) return () => clearInterval(timerId) },[]) }
©MNTSQ, Ltd. 29 ライフサイクルの変化 useEffectの恩恵は何? → 機能的な凝集性が高い const Component =
() => { // API コール useEffect(()=> { const response = apiCall(payload) setResponse(response) }, [payload]) // タイマー処理 useEffect(()=>{ const timerId = setInterval(() => { // tick process }, 1000) return () => clearInterval(timerId) },[]) }
©MNTSQ, Ltd. 30 ライフサイクルの変化 useEffectの恩恵は何? → 機能的な凝集性が高い • APIコール ◦
mount時にAPIコール ◦ payloadのupdate時にAPIコール • タイマー ◦ mount時にタイマーをスタート ◦ unMount時にタイマーをクリア const Component = () => { // API コール useEffect(()=> { const response = apiCall(payload) setResponse(response) }, [payload]) // タイマー処理 useEffect(()=>{ const timerId = setInterval(() => { // tick process }, 1000) return () => clearInterval(timerId) },[]) }
©MNTSQ, Ltd. 31 ライフサイクルの変化 useEffectの恩恵は何? → 機能的な凝集性が高い • APIコール ◦
mount時にAPIコール ◦ payloadのupdate時にAPIコール • タイマー ◦ mount時にタイマーをスタート ◦ unMount時にタイマーをクリア const Component = () => { // API コール useEffect(()=> { const response = apiCall(payload) setResponse(response) }, [payload]) // タイマー処理 useEffect(()=>{ const timerId = setInterval(() => { // tick process }, 1000) return () => clearInterval(timerId) },[]) } 機能的な凝集性が高い→再利用がしやすい
©MNTSQ, Ltd. 32 lifecycle hookは?
©MNTSQ, Ltd. 33 ライフサイクルの変化 lifecycle hookの恩恵は?
©MNTSQ, Ltd. 34 ライフサイクルの変化 lifecycle hookの恩恵は? → 時間的な凝集性が高い
©MNTSQ, Ltd. 35 ライフサイクルの変化 lifecycle hookの恩恵は? → 時間的な凝集性が高い export default
{ watch: { payload: { this.fetchData(); } // APIコール }, mounted() { this.fetchData(); // APIコール this.timerId = setInterval(this.tick, 1000); // タイマー処理 }, beforeUnmount() { clearInterval(this.timerId); // タイマー処理 } };
©MNTSQ, Ltd. 36 ライフサイクルの変化 lifecycle hookの恩恵は? → 時間的な凝集性が高い export default
{ watch: { payload: { this.fetchData(); } // APIコール }, mounted() { this.fetchData(); // APIコール this.timerId = setInterval(this.tick, 1000); // タイマー処理 }, beforeUnmount() { clearInterval(this.timerId); // タイマー処理 } };
©MNTSQ, Ltd. 37 ライフサイクルの変化 lifecycle hookの恩恵は? → 時間的な凝集性が高い export default
{ watch: { payload: { this.fetchData(); } // APIコール }, mounted() { this.fetchData(); // APIコール this.timerId = setInterval(this.tick, 1000); // タイマー処理 }, beforeUnmount() { clearInterval(this.timerId); // タイマー処理 } }; • update ◦ APIコール • mount ◦ APIコール ◦ タイマースタート • unMount ◦ タイマーをクリア
©MNTSQ, Ltd. 38 ライフサイクルの変化 lifecycle hookの恩恵は? → 時間的な凝集性が高い export default
{ watch: { payload: { this.fetchData(); } // APIコール }, mounted() { this.fetchData(); // APIコール this.timerId = setInterval(this.tick, 1000); // タイマー処理 }, beforeUnmount() { clearInterval(this.timerId); // タイマー処理 } }; • update ◦ APIコール • mount ◦ APIコール ◦ タイマースタート • unMount ◦ タイマーをクリア 時間軸で機能は分断される。 物理的なまとまりが無いので機能の関連性を見 つけるのは難しい。
©MNTSQ, Ltd. 39 useEffect と lifecycle比較
©MNTSQ, Ltd. 40 ライフサイクルの変化 useEffect • update ◦ APIコール •
mount ◦ APIコール ◦ タイマースタート • unMount ◦ タイマーをクリア 時間的な凝集性が高い。 いつ何が起きるか分かりやすい。 機能が時間で切られて散らばる。 • APIコール ◦ mount時にAPIコール ◦ payloadのupdate時にAPIコール • タイマー ◦ mount時にタイマーをスタート ◦ unMount時にタイマーをクリア 機能的な凝集性が高い。 機能で再利用がしやすい。 発火タイミングを読み解く必要がある。 lifecycle hook
©MNTSQ, Ltd. 41 実装のアプローチ
©MNTSQ, Ltd. 42 ライフサイクルの変化 Composableのlifecycle hookが◎ Composableで機能的な凝集性が高い lifecycle hook郡を定義できる。 機能的な凝集性の高さを維持しつつ、
内部で発火タイミングも明確化。 function useInterval() { let timerId onMounted(() => { timerId = setInterval(() => { // tick process }, 1000) }); onUnmounted(() => { clearInterval(timerId) }); }
©MNTSQ, Ltd. 43 ライフサイクルの変化 function useInterval() { let timerId onMounted(()
=> { timerId = setInterval(() => { // tick process }, 1000) }); onUnmounted(() => { clearInterval(timerId) }); } Composableで機能的な凝集性が高い lifecycle hook郡を定義できる。 機能的な凝集性の高さを維持しつつ、 内部で発火タイミングも明確化。 Composableのlifecycle hookが◎
©MNTSQ, Ltd. 44 ライフサイクルの変化 function useInterval() { let timerId onMounted(()
=> { timerId = setInterval(() => { // tick process }, 1000) }); onUnmounted(() => { clearInterval(timerId) }); } Composableで機能的な凝集性が高い lifecycle hook郡を定義できる。 機能的な凝集性の高さを維持しつつ、 内部で発火タイミングも明確化。 Composableのlifecycle hookが◎ いいとこどり!
©MNTSQ, Ltd. 45 目次 1. ライフサイクル表現の変化 2. 構文の変化 3. まとめ
©MNTSQ, Ltd. 46 構文の変化
©MNTSQ, Ltd. 47 構文の変化 React(JSX) <Button className="red" onClick={submit} data-cy="submitButton" >
Save </Button> Vue(テンプレート) <Button class="red" @click="submit" data-cy="submitButton" > Save </Button>
©MNTSQ, Ltd. 48 構文の変化 React(JSX) <Button className="red" onClick={submit} data-cy="submitButton" >
Save </Button> Vue(テンプレート) <Button class="red" @click="submit" data-cy="submitButton" > Save </Button> 一番大きな変化
©MNTSQ, Ltd. 49 構文の変化 React(JSX) <Button className="red" onClick={submit} data-cy="submitButton" >
Save </Button> Vue(テンプレート) <Button class="red" @click="submit" data-cy="submitButton" > Save </Button> Vueには詳しいと思うので、、、
©MNTSQ, Ltd. 50 構文の変化 ReactのJSXって??
©MNTSQ, Ltd. 51 構文の変化 ReactのJSXって??
©MNTSQ, Ltd. 52 構文の変化 ReactのJSXって?? JSX (悪口が聞こえたような...)
©MNTSQ, Ltd. 53 構文の変化 ReactのJSXって?? 気持ち悪い ≒ よく知らないから?
©MNTSQ, Ltd. 54 JSXとは何者なのか?
©MNTSQ, Ltd. 55 構文の変化 JSXはJavaScriptの構文拡張 • テンプレート拡張じゃない • JavaScriptとXMLの組み合わせ •
ECMAScript2015に対する構文拡張 x =
©MNTSQ, Ltd. 56 構文の変化 JSXはJavaScriptの構文拡張 • テンプレート拡張じゃない • JavaScriptとXMLの組み合わせ •
ECMAScript2015に対する構文拡張 x = なにがJavaScriptに拡張されたの?
©MNTSQ, Ltd. 57 構文の変化 JSXはJavaScriptの構文拡張 • テンプレート拡張じゃない • JavaScriptとXMLの組み合わせ •
ECMAScript2015に対する構文拡張 x = なにがJavaScriptに拡張されたの? JSX.Element型
©MNTSQ, Ltd. 58 構文の変化 JSXはJavaScriptの構文拡張 • テンプレート拡張じゃない • JavaScriptとXMLの組み合わせ •
ECMAScript2015に対する構文拡張 • JSX.Element型が使える • TypeScriptが言語サポート x = const str: string = "hello world" const Element: JSX.Element = <span>hoge</span>
©MNTSQ, Ltd. 59 なぜReactはJSXなのか?
©MNTSQ, Ltd. 60 構文の変化 なぜReactはJSXなのか? →コンポーネントという関心の分離にフォーカスするため
©MNTSQ, Ltd. 61 構文の変化 なぜReactはJSXなのか? →コンポーネントという関心の分離にフォーカスするため
©MNTSQ, Ltd. 62 構文の変化 なぜReactはJSXなのか? →コンポーネントという関心の分離にフォーカスするため 分離すべきはコンポーネント。
©MNTSQ, Ltd. 63 構文の変化 なぜReactはJSXなのか? <template> <div></div> </template> <script> </script>
→コンポーネントという関心の分離にフォーカスするため 分離すべきはコンポーネント。
©MNTSQ, Ltd. 64 構文の変化 なぜReactはJSXなのか? <template> <div></div> </template> <script> </script>
→コンポーネントという関心の分離にフォーカスするため 分離すべきはコンポーネント。 UI・ロジックではない。 技術の分離は関心の分離には寄与しない。
©MNTSQ, Ltd. 65 構文の変化 なぜReactはJSXなのか? <template> <div></div> </template> <script> </script>
分離すべきはコンポーネント。 UI・ロジックではない。 技術の分離は関心の分離には寄与しない。 であれば一つの技術(JavaScript)の表現力を活かし コンポーネントの分離にフォーカスする。 JavaScriptドリブン →コンポーネントという関心の分離にフォーカスするため
©MNTSQ, Ltd. 66 構文の変化 なぜReactはJSXなのか? Reactチーム初期メンバー: Pete Hunt React rethinking
best practice Building components, not templates A framework cannot know how to separate your concerns for you. テンプレートではなくコンポーネントをつくる。 フレームワークは開発者がどのように関心の分離をするのか 分からない。
©MNTSQ, Ltd. 67 ではVueは?
©MNTSQ, Ltd. 68 構文の変化 Vueもやりたいことは同じ なぜSFCなのか(why-sfc) 関心の分離がファイルタイプの分離と同じではない コンポーネント内では、そのテンプレート、ロジック、およびスタイルが本質的に 結合されており、それらを連結することで、実際にコンポーネントがよりまとまり、 保守しやすくなります。
公式ドキュメントより
©MNTSQ, Ltd. 69 構文の変化 Vueもやりたいことは同じ なぜSFCなのか(why-sfc) 関心の分離がファイルタイプの分離と同じではない コンポーネント内では、そのテンプレート、ロジック、およびスタイルが本質的に 結合されており、それらを連結することで、実際にコンポーネントがよりまとまり、 保守しやすくなります。
SFCという概念が独立性の高いコンポーネントを作るギブス 公式ドキュメントより
©MNTSQ, Ltd. 70 構文の違い≒思想の違い
©MNTSQ, Ltd. 71 構文の変化 Webアプリケーションの捉え方 React Vue <template> <body> <header>
{{ header }} </header> <main> {{ content }} </main> <footer> {{ footer }} </footer> </body> <template> React React-pdf React Native アプリケーションのレンダリング先がブラウザ 動的なHTMLテンプレート
©MNTSQ, Ltd. 72 構文の変化 思考の切り替え React UI(JSX)を返す関数を書く // JSX {condition
&& <span>Visible</span>} <ul> {items.map(item => <li key={item.id}>{item.name}</li>)} </ul> <!-- Vue Template --> <span v-if="condition">Visible</span> <ul> <li v-for="item in items" :key="item.id">{{ item.name }}</li> </ul> Vue ディレクティブ等で動的なHTMLを作る
©MNTSQ, Ltd. 73 目次 1. 構文の変化 2. ライフサイクル表現の変化 3. まとめ
©MNTSQ, Ltd. 74 まとめ
©MNTSQ, Ltd. 75 まとめ まとめ • useEffectはムズい。 • lifecycle hookは機能的な凝集を意識
• ReactはJavaScriptドリブン • Vueは動的HTML ◦ (Vapor modeに期待)
©MNTSQ, Ltd. 76 ご清聴ありがとうございました。
None