What about React in ReasonML?

Luke


twitter / github

@czystyl

ReasonReact

let component = ReasonReact.statelessComponent("greeting");

let make = (~name, _children) => {
  ...component,
  render: self => {
    let message =
      "Hello " ++ name ++ "👋";

    <div> (ReasonReact.string(message)) </div>;
  },
};

Stateless

type state = {count: int};

type action =
  | Click;

let component = ReasonReact.reducerComponent("greeting");
 
let make = (~greeting, _children) => {
  ...component,

  initialState: () => {count: 0},

  reducer: (action, state) =>
    switch (action) {
    | Click => ReasonReact.Update({...state, count: state.count + 1})
    },

  render: self => {
    let message =
      "You've clicked this " ++ string_of_int(self.state.count) ++ " times(s)";

    <div>
      <button onClick=(_event => self.send(Click))>
        (ReasonReact.string(message))
      </button>      
    </div>;
  },
};

Stateful

Bindings

[@bs.module "google-map-react"]
external reactClass: ReasonReact.reactClass = "default";

type center = {
  lat: float,
  lng: float,
};

type keys = {key: string};

let make =
    (~defaultZoom: int, ~defaultCenter: center, ~bootstrapURLKeys: keys) =>
  ReasonReact.wrapJsForReason(
    ~reactClass=googleMap,
    ~props={
      "defaultZoom": defaultZoom,
      "defaultCenter": defaultCenter,
      "bootstrapURLKeys": bootstrapURLKeys,
    },
  );

Bindings output

// Generated by BUCKLESCRIPT VERSION 5.0.3, PLEASE EDIT WITH CARE
'use strict';

var ReasonReact = require("reason-react/src/ReasonReact.js");
var GoogleMapReact = require("google-map-react");

function make(defaultZoom, defaultCenter, bootstrapURLKeys) {
  var partial_arg = {
    defaultZoom: defaultZoom,
    defaultCenter: defaultCenter,
    bootstrapURLKeys: bootstrapURLKeys
  };
  var partial_arg$1 = GoogleMapReact.default;
  return (function (param) {
      return ReasonReact.wrapJsForReason(partial_arg$1, partial_arg, param);
    });
}

exports.make = make;
/* ReasonReact Not a pure module */

Looking good,

but where are the HOOKS???

Unfortunately, not there...

But, maybe

ReactReason 0.7 with JSX3

  [@react.component]
  let make = (~name) => {
    let message = "Hello " ++ name ++ "👋";

    <div> {ReasonReact.string(message)} </div>;
  };

New Stateless

type state = {count: int};

type action =
  | Click;

[@react.component]
let make = () => {
  let (state, dispatch) =
    React.useReducer(
      (state, action) =>
        switch (action) {
        | Click => {count: state.count + 1}
        },
      {count: 0},
    );

  let message =
    "You've clicked this " ++ string_of_int(state.count) ++ " times(s)";

  <div>
    <button onClick={_event => dispatch(Click)}>
      {ReasonReact.string(message)}
    </button>
  </div>;
};

New Stateful with a hook

type center = {
  lat: float,
  lng: float,
};

type keys = {key: string};

[@react.component] [@bs.module "google-map-react"]
external make:
  (
    ~defaultZoom: int,
    ~defaultCenter: center,
    ~bootstrapURLKeys: keys,
    ~children: React.element
  ) =>
  React.element =
  "default";

New bindings

// Generated by BUCKLESCRIPT VERSION 5.0.3, PLEASE EDIT WITH CARE
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */

New bindings output

aka zero cost bindings

Demo

ReasonApollo

Graphql_ppx

module GetLocation = [%graphql
  {|
  query getLocation ($ipAddress: String!) {
    getLocation(ip: $ipAddress) {
      location {
        latitude
        longitude
      }
      country {
        iso_code
      }
    }
  }
|}
];

wrong query

Query component

module GetLocationQuery = ReasonApollo.CreateQuery(GetLocation);

/* render */
<GetLocationQuery>
  ...{({result}) =>
    <div>
      {switch (result) {
       | Loading => ReasonReact.string("Loading...")
       | Error(_) => ReasonReact.string("Error occured")
       | Data(data) =>
         switch (data##getLocation) {
         | Some(location) => <Map location />
         | None => <Map />
         }
       }}
    </div>
  }
</GetLocationQuery>

Demo

Thanks

Made with Slides.com