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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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.4k
Designing and maintaining an open-source React Native library
zoontek
0
130
Manage microservices like a Chef
zoontek
0
1.3k
Other Decks in Technology
See All in Technology
生成 AI 実践ガイド (概略版) AIガバナンス編
asei
0
140
Kiroで書いた 設計書 が AI レビューの 採点基準 になる
ezaki
0
140
【Cyber-sec+】経営層を"動かす"ための考え方
hssh2_bin
0
200
白金鉱業Meetup_Vol.24_「AIエージェントは分けるほど良い」は本当か? / Is it true that “the more you divide AI agents, the better”?
brainpadpr
1
420
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.6k
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
440
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
160
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
290
10年間のブログ発信を振り返って見えたWebアプリケーションエンジニアとしての軌跡
stefafafan
0
170
PostgreSQL 19 新機能概要 OSC Hokkaido 2026
nori_shinoda
0
190
ACE-Step-1.5で見る 音楽生成AIのしくみと“破綻だけ直す”Retake機能の開発【zennfes spring 2026 登壇資料】
personabb
1
550
Kiro Ambassador を目指す話
k_adachi_01
0
110
Featured
See All Featured
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
ラッコキーワード サービス紹介資料
rakko
1
3.7M
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Navigating Weather and Climate Data
rabernat
0
220
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
A better future with KSS
kneath
240
18k
Google's AI Overviews - The New Search
badams
0
1k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
160
Building Flexible Design Systems
yeseniaperezcruz
330
40k
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 ?