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
ReactNative + microCMS の設計にすごく悩んだ話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
hiroya iizuka
March 04, 2021
Technology
1.2k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ReactNative + microCMS の設計にすごく悩んだ話
hiroya iizuka
March 04, 2021
More Decks by hiroya iizuka
See All by hiroya iizuka
学問と資産
hiroyaiizuka
0
510
clean architecture と経営
hiroyaiizuka
0
1.5k
既存のRESTful な RailsプロジェクトにGraphQL導入を検討した話
hiroyaiizuka
0
5.1k
3つのNext.jsプロジェクトを 新卒エンジニアと一緒に 開発した話
hiroyaiizuka
1
470
実戦に役立つFirebase_Analytics_使用集
hiroyaiizuka
0
180
Other Decks in Technology
See All in Technology
CDKで書くECSのベストプラクティス、 改めて考え直す2026 #cdkconf2026
makies
3
830
AI Driven AI Governance
pict3
0
490
「守りたい体験」を渡すだけで E2E を生成させられるようになった話
hinac0
1
600
ガバナンスの「ちょうどいい落とし所」を探れ!開発スピードを妨げない運用判断の勘所 / SRE NEXT 2026
genda
1
250
Making sense of Google’s agentic dev tools
glaforge
1
280
kaonavi Tech Night#1
kaonavi
0
110
CSに"SLO"は要らない、経営層に"99.9%"は伝わらない - SREを全社に"翻訳"する3原則
cscengineer
PRO
1
5.1k
非定型なドキュメントを効率よくリファクタする 〜えぇ!?仕様書27本の移行が1日で終わったって!?〜
subroh0508
2
560
しくみを学んで使いこなそう GitHub Copilot app
torumakabe
2
290
AI、CDK と協働する Full TypeScript アプリケーション開発 / Full TypeScript Application with AI and CDK
geekplus_tech
2
400
型は壁、Rustでもバグを直すな、表現できなくせよ
nwiizo
14
2.1k
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
3
330
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
220
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Google's AI Overviews - The New Search
badams
0
1.1k
From π to Pie charts
rasagy
0
240
The Mindset for Success: Future Career Progression
greggifford
PRO
0
420
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
Between Models and Reality
mayunak
4
370
Transcript
ReactNative + microCMS の設計にすごく悩んだ話 株式会社BeatFit CTO 飯塚 浩也
医師 循環器内科、総合診療医と して、⼤学 - 地⽅の病院を 8 年間勤務。 IT は⼤の苦⼿。 パソコン教室のアビバに
通っていた。 エンジニア 株式会社BeatFit にエンジニ アとして⼊社。 [ ⽇課] Codewars, LeetCode Hack The Box Type Challenge
今⽇のお話 Headless CMS の技術選定に⾄るまでの経緯 悩んだ設計の話 CMS との差分を埋める React Native ライブラリ
みんなの広場
None
弊社運営チームは CMS から投稿したい でも、CMS 周りを コーディング したくない 期限まで あと3 ヶ⽉しかない
そうだ microCMS でいこう
運⽤⾯ ・⽇本語が魅⼒的だった ・中の⼈が、twitter で だった ・料⾦プランが、優しかった 友達
いいね、返信 コメント、通知など 複雑な機能がある React Native での 事例の少なさ よくある HeadlessCMS の
Usecase と違う・・・
実際に悩んだ設計
設計 1. 責務を分離 通常の Feed コンテンツは、CMS ヘ 複雑なwrite 要件のデータは、RDS へ
Get request 時に、frontend 側で mapping するロジックが必要になる 😣
WebHook を使い、CMS 上 からの投稿や削除が可能。 運営が、不適切な投稿を、CMS でチェックできる。 設計 2. 全データを microCMS
で管理
データの⼆重管理になり、データ不整合が⼼配。 定期的に同期をする処理が必要になる。 Post request が多く、コストが⾼くなる。 設計 2.
twitter でぶつぶつ悩んでたら → microCMS 創業者 ( 柴⽥さん、松⽥さん) からDM
神対応、ありがとうございました・・・!😭
最終設計: こうなりました!
最終設計: Usecase での分離 運営の投稿 User の投稿
Appendix Usecase で分離することで、設計が simple になった Post request が少ない設計になり、費⽤⾯で優れた 運営側の投稿のカスタマイズを、細かくできる設計になった 運営側の投稿頻度は少なく、当⾯は
Webhook 通信の失敗は 許容できる設計になった
microCMS との差分を埋める ライブラリーのご紹介 react-native-rich-editor react-native-render-html
Rich Editor in microCMS "textContent": "<p><br></p><h2 id=\"hf99e890528\"> あああいいい</h2> <p><a ref=\"https://beatfit.jp\"target=\"_blank\"
rel=\"noopenernoreferrer\"> アイウエオ</a><br><br> </p>", ↓
react-native-rich-editor
HTML を取得 const richText = useRef<RichEditor | null>() const html
= richText.current?.getContentHtml() <RichEditor ref={r => (richText.current = r)} placeholder={' ⼊⼒してください'} onChange={handleChange} initialFocus /> 1 2 3 4 5 6 7 8 9 10
HTML を取得 const richText = useRef<RichEditor | null>() const html
= richText.current?.getContentHtml() <RichEditor ref={r => (richText.current = r)} placeholder={' ⼊⼒してください'} onChange={handleChange} initialFocus /> 1 2 3 4 5 6 7 8 9 10 const html = richText.current?.getContentHtml() const richText = useRef<RichEditor | null>() 1 2 3 4 <RichEditor 5 ref={r => (richText.current = r)} 6 placeholder={' ⼊⼒してください'} 7 onChange={handleChange} 8 initialFocus 9 /> 10
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 5 6 7 8 9 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> 16 </ScrollView> 17 ); 18 } 19
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 5 6 7 8 9 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> 16 </ScrollView> 17 ); 18 } 19 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 const htmlContent = ` 5 <h1>This HTML snippet is now rendered with native components !</h1> 6 <h2>Enjoy a webview-free and blazing fast application</h2> 7 <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> 8 <em style="textAlign: center;">Look at how happy this native cat is</em> 9 `; 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 16 </ScrollView> 17 ); 18 } 19
まとめ 設計に悩んだときは、UseCase で分離すると単⼀責任に なり、設計が simple になる microCMS は、複雑な機能が必要な時も、有効な選択肢 となる react-native-render-html
と react-native-rich-editor で 差分を埋められる