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
540
Other Decks in Technology
See All in Technology
Claude Codeから見る、エンジニアの世界の変容とその先
oikon48
7
4.6k
AWSDirectConnectの構築の進め方を整理してみた
masa_my
1
200
Vibe-to-Spec開発_実践ガイド
happysamurai294
0
110
「社外イベント=意識高い」の壁を壊せ!元々無関心だった僕らが部内で社外イベントを民主化して15人を連れ出すまで
say_no_w
0
160
AI秘書と毎日働くのはもう当たり前。開発以外の業務に足りない機能をどう埋める?
minorun365
PRO
4
1.9k
Let's Change Our World—Again
snoozer05
PRO
6
700
自宅サーバと脆弱性
masakiokuda
1
120
演劇と私とスクラム
chinmo
0
160
ビジネス部門からPOを迎えての半年間の進歩と課題
zozotech
PRO
0
150
E2Eってつらくないですか?E2Eの管理コストを下げる手段とその実践
akaboshinit
5
2.4k
AIコーディングを実践してきた1年を振り返る / Looking Back on a Year of Practicing AI Coding
takedatakashi
1
150
[re:Invent2026事前勉強会(有志開催)]続きは、ラスベガスの廊下で / continue-in-the-vegas-hallway
sh_fk2
0
310
Featured
See All Featured
Color Theory Basics | Prateek | Gurzu
gurzu
1
500
Testing 201, or: Great Expectations
jmmastey
46
8.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
640
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
430
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Exploring anti-patterns in Rails
aemeredith
4
540
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
610
A Soul's Torment
seathinner
8
3.8k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
620
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