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
Des apps multiplateformes avec reason-react-native
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Mathieu Acthernoene
May 21, 2019
Technology
100
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Des apps multiplateformes avec reason-react-native
Mathieu Acthernoene
May 21, 2019
More Decks by Mathieu Acthernoene
See All by Mathieu Acthernoene
Advanced TypeScript: How we made our router typesafe
zoontek
3
1.5k
Designing and maintaining an open-source React Native library
zoontek
0
140
Manage microservices like a Chef
zoontek
0
1.3k
Other Decks in Technology
See All in Technology
秘密度ラベル初心者が第1歩でつまづかないための「設計・運用」ポイント
seafay
PRO
1
520
小さいから、全部わかる。— 常駐AI "xangi" のすすめ
sugupoko
0
160
AI Agentをシステムに組み込む前にゆるく向き合ってみる
hayama17
0
170
元・セキュリティ学習経験0大学生による業務紹介 / An Introduction to the Job by a Former College Student with Zero Security Training Experience
nttcom
0
1k
AWS Summit 2026で見えたSIerにとっての Amazon Quickの位置づけ
maf_0521
0
120
スタートアップにAmazon EKSは早すぎる? マルチプロダクト戦略を加速する Platform Engineeringの実践 / Is Amazon EKS Too Soon for Startups? Practical Platform Engineering to Accelerate a Multi-Product Strategy
elmodev09
1
1.9k
そこにあるから地図ができる~位置を示す"モノ"を愉しむ~ - Interface 2026年6月号GPS特集オフ会 / interface_202606_GPS_offline
sakaik
1
130
本当の”仕事”を手放せる未来が見えた
mu7889yoon
0
200
SRE歴2ヶ月でも開発6年の知見を活かして、チームで止まっていた環境改善を前に進めた話
a_ono
0
130
Multi-Agent並列開発を 安全に回すための技術 / Technology for Safely Multi-Agent Parallel Development
tooppoo
0
220
飲食店もAIで。レジ締めやハンディシステムをつくってる話 / Using AI for restaurant management
vtryo
0
210
自作お家AIエージェントスタックチャンFWで困っている所紹介
74th
0
160
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
55k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.6k
Abbi's Birthday
coloredviolet
3
8.3k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
950
A Modern Web Designer's Workflow
chriscoyier
698
190k
Embracing the Ebb and Flow
colly
88
5.1k
The Pragmatic Product Professional
lauravandoore
37
7.3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
470
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Transcript
! 1 Multi-platforms apps with reason-react-native
! 2 Mathieu Acthernoene @zoontek
! 3 ⏱ Disclaimer 30 min is short I will
be brief on non-primary points
! 4 React Native A mobile framework to build user
interfaces Supported platforms : iOS, Android & UWP
! 5 React Native <View /> Credit : Formidable labs
UIView android.view.View
! 6 ReasonML Alternate syntax + tooling for OCaml Looks
like modern JavaScript
! 7 let a = 1; /* int */ let
b = 1.0; /* float */ let c = "Hello"; /* string */ let d = 'Z'; /* char */ let e = true; /* boolean */ let f = [1, 2, 3]; /* list(int) */ let g = [|1, 2, 3|]; /* array(int) */ let h = Some(x); /* option('a) */ let i = (); /* unit */ ReasonML
! 8 type user = { name: string, age: int,
}; let me = { name: “Matthieu", age: 27, }; let meLater = { ...me, age: 28, }; ReasonML
! 9 ReasonML let sayHi = name X> Js.log("Hi "
Z[ name Z[ “!”); let add = (a, b) X> a +. b;
! 10 BuckleScript OCaml to ES5 JS compiler Supports both
syntaxes
! 11 UIView android.view.View compile time runtime time
! 12 $ Let’s create a project
! 13
! 14 Highly complex backend A Google Cloud Function which
run Puppeteer every hour (with Cloud Scheduler) and store a JSON file
! 15 { "dates": [ "2019-05-19", "2019-05-20", // … ],
"pools": [ { "id": "alfred-nakache", "name": "Alfred Nakache", "coordinates": { "latitude": 48.871687, "longitude": 2.378887 }, "hours": [ [["08:00", "18:00"]], [], [["07:00", "08:30"], ["11:30", "13:30"], ["16:30", "18:00"]] // … Backend
! 16 $ brew install node yarn watchman $ yarn
global add react-native-cli reason-cli@latest-macos Things you should install — or —
! 17 $ react-native init ParisPiscine && cd ParisPiscine
! 18 $ yarn add --dev bs-platform $ yarn add
reason-react $ yarn add git://github.com/reasonml-community/bs- react-native#756f2f34fefeed1c3d1ed389330278ecd0434aca $ yarn add bs-fetch @glennsl/bs-json # extras $ touch bsconfig.json
! 19 // bsconfig.json { "name": "paris-piscine", "version": "0.1.0", "suffix":
".bs.js", "refmt": 3, "warnings": { "error": "+101" }, "reason": { "react-jsx": 3 }, "bs-dependencies": [ "@glennsl/bs-json", "bs-fetch", "reason-react", "bs-react-native-monorepo/reason-react-native" ], // …
! 20 // …bsconfig.json "package-specs": { "module": "es6", "in-source": true
}, "sources": { "dir": "src", "subdirs": true }, "js-post-build": { "cmd": "./node_modules/bs-react-native-monorepo/ git-monorepo-usage-trick" } }
! 21 // package.json { "name": "paris-piscine", "version": "0.0.1", "scripts":
{ "bs:clean": "bsb -clean-world", "bs:start": "bsb -make-world -w", "bs:build": "bsb -make-world", "rn:start": "node node_modules/react-native/ local-cli/cli.js start" }, // …
! 22 $ rm -rf .buckconfig .flowconfig __tests__ App.js $
mkdir src && touch src/App.re A bit of cleanup
! 23 // src/App.re open ReactNative; let styles = StyleSheet.create(
Style.{ "container": style(~flex=1., ~alignItems=`center, ~justifyContent=`center, ()), "text": style(~fontSize=24., ()), }, );
! 24 // …src/App.re [@react.component] let make = () X>
{ <View style=styles##container> <Text style=styles##text> "Hello LilleFP”u>React.string </Text> </View>; };
! 25 // src/App.bs.js // Generated by BUCKLESCRIPT VERSION 5.0.3
import * as React from "react"; import * as ReactNative from "react-native"; var styles = ReactNative.StyleSheet.create({ container: { alignItems: “center”, flex: 1, justifyContent: “center”, }, text: { fontSize: 24 }, });
! 26 // …src/App.bs.js function App(Props) { return React.createElement(ReactNative.View, {
style: styles.container, children: React.createElement(ReactNative.Text, { style: styles.text, children: "Hello LilleFP", }), }); } var make = App; export { styles, make };
! 27 // index.js import { AppRegistry } from "react-native";
import { make as App } from "./src/App.bs.js"; import { name as appName } from "./app.json"; AppRegistry.registerComponent(appName, () X> App);
! 28
! 29
! 30 // Pools.re let url = "http://localhost:8080"; type coordinates
= { latitude: float, longitude: float, }; type pool = {coordinates}; type fetchedData = { dates: array(string), pools: array(pool), }; Fetching & decoding data
! 31 // …Pools.re module Decode = { open Json.Decode;
let coordinates = json X> { latitude: field("latitude", float, json), longitude: field("longitude", float, json), }; let pool = json X> {coordinates: field("coordinates", coordinates, json)}; let fetchedData = json X> { dates: field("dates", array(string), json), pools: field("pools", array(pool), json), }; }; Fetching & decoding data
! 32 // …Pools.re let fetchData = () X> Js.Promise.(
Fetch.fetch(url) yz then_(Fetch.Response.json) yz then_(json X> Decode.fetchedData(json)u>resolve) ); Fetching & decoding data
! 33 // App.re open ReactNative; open Belt; type state
= | Loading | Error | Loaded(Pools.fetchedData); type action = | FetchData | ReceiveError | ReceiveData(Pools.fetchedData); Displaying data
! 34 // …App.re let styles = StyleSheet.create( Style.{ "container":
style(~flex=1.,~alignItems=`center, ~justifyContent=`center, ()), }, ); Displaying data
! 35 // …App.re [@react.component] let make = () X>
{ let (state, dispatch) = React.useReducer( (state, action) X> switch (action) { | FetchData X> Loading | ReceiveError X> Error | ReceiveData(data) X> Loaded(data) }, Loading, ); Displaying data
! 36 // …App.re [@react.component] let make = () X>
{ // … let displayFetchingError = () X> Alert.alert( ~title={js|Une erreur est survenue|js}, ~message={js|Impossible d'accéder aux données|js}, (), ); Displaying data
! 37 React.useEffect1(() X> { Js.Promise.( Pools.fetchData() yz then_((data: Pools.fetchedData)
X> dispatch(ReceiveData(data))u>resolve ) yz catch(_error X> { displayFetchingError(); dispatch(ReceiveError)u>resolve; }) yz ignore ); None; }, [||]); Displaying data
! 38 <View style=styles##container> {switch (state) { | Loading X>
<ActivityIndicator size=ActivityIndicator.Size.large /> | Error X> React.null | Loaded(data) X> switch (data.pools[0]) { | Some(pool) X> <Text> {("First pool: " Z[ pool.name)u>React.string} </Text> | None X> <Text> "No pool found"u>React.string </Text> } }} </View> Displaying data
! 39 All of this is cool, yeah But how
do I use existing libs ?
! 40 $ yarn add react-navigation react-native-gesture-handler react-native-maps $ react-native
link react-native-gesture-handler $ react-native link react-native-maps Let’s add some deps
! 41 // src/vendor/ReactNavigation.re type stackNavigatorConfig; type navigationProp('routeParams, 'pushedParams) =
{ . [@bs.meth] "push": (string, 'pushedParams) X> unit, [@bs.meth] "goBack": unit X> unit, "state": { . "key": string, "routeName": string, "params": 'routeParams, }, }; Binding example n°1 (react-navigation)
! 42 // …src/vendor/ReactNavigation.re [@bs.obj] external stackNavigatorConfig: (~headerMode: [@bs.string] [
| `float | `screen | `none]=?, unit) X> stackNavigatorConfig = ""; [@bs.module "react-navigation"] external createStackNavigator: (Js.t('a), stackNavigatorConfig) X> React.element = ""; [@bs.module "react-navigation"] external createAppContainer: React.element X> React.element = ""; Binding example n°1 (react-navigation)
! 43 // src/vendor/MapView.re open ReactNative; include NativeElement; type region;
[@bs.obj] external region: ( ~latitude: float, ~longitude: float, ~latitudeDelta: float, ~longitudeDelta: float ) X> region = ""; Binding example n°2 (react-native-maps)
! 44 // …src/vendor/MapView.re [@react.component] [@bs.module "react-native-maps"] external make: (
~ref: ref=?, ~style: Style.t=?, ~region: region=?, ~children: React.element=? ) X> React.element = "default"; Binding example n°2 (react-native-maps)
! 45 & Diving in the full codebase
! 46 Thank you ! Questions ?