Skip to content

Instantly share code, notes, and snippets.

@jordwalke
Last active December 13, 2021 17:32
Show Gist options
  • Save jordwalke/67819c91df1552009b22 to your computer and use it in GitHub Desktop.
Save jordwalke/67819c91df1552009b22 to your computer and use it in GitHub Desktop.
React OCaml API
open ReactDOM
module MyComponent = struct
(* Component Properties *)
type props = {count: int}
(* Hey, state can be any type! *)
type state = string
(* Initializer *)
let getInitialState props = "neverBeenClicked"
(* Signal handlers - these simply return the next state. *)
let componentWillReceiveProps props (prevProps, prevState) = prevState
let handleClick {props; state; updater} evt = "hasBeenClicked"
(* Render: props and state as arguments, just like we've always wanted *)
let render {props; state; updater} = [
Div.make
~styleString: "Omit to rely on defaults #thanksOCaml - no really, thanks OCaml"
~className: ("P:" ^ props.prefix ^ " S:" ^ state)
~onClick: (updater handleClick)
~children: []
]
end
(* CreateComponent as a Functor. OCaml's (SML's) module system proves to be very powerful *)
module MyComponentClass = React.CreateComponent (MyComponent)
@jordwalke
Copy link
Author

A few things to note:

  • See how next states are always returned.
  • All functions take state/props and an updater in its arguments. Because OCaml, you can omit some of the record fields such as render {props} if you only use a subset of them.
  • For DOM components, we can take advantage of default args which can act more powerfully than row polymorphic records.
  • OCaml has a very nice ppx syntax extension mode that actually could serve as the JSX equivalent out of the box! I actually like it better than JSX.
       {div| className="blah"
           {span|
             hello
           |span}
        |div}
  • OCaml's powerful module system helps include/inherit base functionality without resorting to Object Oriented patterns.

@jordwalke
Copy link
Author

Also, see how we can use OCaml's every-file-is-a-module feature to make the API even simpler:

https://gist.github.com/jordwalke/c60c91ff6c82d47bf605

This is consistent with react-future's module pattern example https://github.com/reactjs/react-future/blob/master/06%20-%20Returning%20State/02%20-%20Module%20Pattern.js

@Drup
Copy link

Drup commented Mar 30, 2016

OCaml has a very nice ppx syntax extension mode that actually could serve as the JSX equivalent out of the box! I actually like it better than JSX.

   {div| className="blah"
       {span|
         hello
       |span}
    |div}

fwiw, nesting of the same element doesn't work with that.

@IwanKaramazow
Copy link

What's the purpose of updater, I mean what does it do ?

@jordwalke
Copy link
Author

Sorry for the late reply - I suspect @IwanKaramazow knows what updater is for now - now that he actually implemented it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment