Skip to content

Instantly share code, notes, and snippets.

@ducaale
Last active September 30, 2020 08:11
Show Gist options
  • Save ducaale/09c1541b0150510302fdf53e2e50ebaf to your computer and use it in GitHub Desktop.
Save ducaale/09c1541b0150510302fdf53e2e50ebaf to your computer and use it in GitHub Desktop.
Notes on using brisk-reconciler in OCaml

There are two ways to declare a component in brisk-reconciler:

  1. By using a normal function
let%component counterButtons = () => {
  let%hook (count, setCount) = Hooks.state(0);

  <view>
    <button title="Decrement" onPress={() => setCount(count => count - 1)} />
    <text text={"Counter: " ++ str(count)} />
    <button title="Increment" onPress={() => setCount(count => count + 1)} />
  </view>;
};

let render = () =>
  <view>
    <counterButtons />
  </view>
  1. By using a make function inside a module
module CounterButton = {
  let%component make = () => {
    let%hook (count, setCount) = Hooks.state(0);

    <view>
      <button title="Decrement" onPress={() => setCount(count => count - 1)} />
      <text text={"Counter: " ++ str(count)} />
      <button title="Increment" onPress={() => setCount(count => count + 1)} />
    </view>;
  };
}

let render = () =>
  <view>
    <CounterButtons />
  </view>

JSX equavalent in OCaml

In brisk-reconciler, the following JSX

<view> <text text="Hello World" /> <CounterButtons /> </view>;

is roughly translated to something like this

view(~children=[text(~text="Hello World", ()), CounterButtons.make(()) ] |> listToElement, ());

There are two things worth noting here:

  1. In JSX land, modules and functions are called the same way (except for the capitalization of the first letter) where in the bare syntax, we need to explicitly call the make function inside the module
  2. Components take an optional key parameter which means we need to pass unit argument to terminate the currying. In JSX, we don't need to do such thing

We can write helper functions for a nicer syntax in OCaml.

let view children = view ~children:(listToElement children) ();;

view [
  button ~title:"Decrement" ~onPress:(fun () -> setCount(fun count -> count - 1)) ();
  text ~text:("Counter: " ^ string_of_int count) ();
  button ~title:"Increment" ~onPress:(fun () -> setCount(fun count -> count + 1)) ();
];;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment