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
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
110
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
150
Manage microservices like a Chef
zoontek
0
1.3k
Other Decks in Technology
See All in Technology
予測不能な実行エージェントを安全にサクッと試せるサンドボックス環境の話
sansantech
PRO
0
120
カンファレンスに参加した後の浮遊感とセルフケア
pauli
0
310
並行性の問題を防げ!実践トランザクション入門
occhi
0
270
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
840
[2026 Oracle Technical Deep Dive] オンプレミスDBのCloud移行アプローチ:移行計画に基づくメソッドとツールの選択 (2026年9月17日開催)
oracle4engineer
PRO
0
150
FinTech 1-2 : Overview of FinTech
ks91
PRO
0
150
IR Today: Theory, Practice, and Agents
dtunkelang
0
350
20260930_Gemma4_Hands-on
tsho
0
230
形式手法を使って仕様をコーディングしよう
mikanichinose
0
180
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
2
390
今こそ知りたいAmplifyGen2
mkdev10
2
150
生成AIで高い生産性を求められて、 悩み、乗り越えた話
mot_techtalk
2
130
Featured
See All Featured
Google's AI Overviews - The New Search
badams
0
1.6k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
490
Darren the Foodie - Storyboard
khoart
PRO
4
4k
How STYLIGHT went responsive
nonsquared
100
6.3k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Claude Code のすすめ
schroneko
67
230k
It's Worth the Effort
3n
188
29k
How to Talk to Developers About Accessibility
jct
2
560
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
390
Raft: Consensus for Rubyists
vanstee
142
7.7k
Building AI with AI
inesmontani
PRO
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 ?