Skip to content

Instantly share code, notes, and snippets.

@adrianmcli
Created February 14, 2017 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrianmcli/ad8077fa63d709ae7b95fd4fc29c2616 to your computer and use it in GitHub Desktop.
Save adrianmcli/ad8077fa63d709ae7b95fd4fc29c2616 to your computer and use it in GitHub Desktop.
Finished source files for the Reason workshop
module Counter = {
include ReactRe.Component.Stateful;
let name = "Counter";
type state = {count: int};
type props = unit;
let getInitialState _ => {count: 0};
/** increment handler */
let handleIncrement {state} _ => {
Js.log "clicked increment!";
Some {count: state.count + 1}
};
/** decrement handler */
let handleDecrement {state} _ => {
Js.log "clicked decrement!";
Some {count: state.count - 1}
};
/** render */
let render {state, updater} =>
<div>
<h1> (ReactRe.stringToElement (string_of_int state.count)) </h1>
<button onClick=(updater handleIncrement)> (ReactRe.stringToElement "Increment") </button>
<button onClick=(updater handleDecrement)> (ReactRe.stringToElement "Decrement") </button>
</div>;
};
include ReactRe.CreateComponent Counter;
let createElement = wrapProps ();
let () =
ReactDOMRe.render (createElement children::[] ()) (ReasonJs.Document.getElementById "index");
module CounterAPI = {
let then_ a b => ReasonJs.Promise.thenDo b a;
let fetchAndUpdate action setState => {
let p = ReasonJs.fetch ("https://rehydrate-workshop-server-coescnwddb.now.sh/" ^ action);
let _ = p |> then_ ReasonJs.Response.text |> then_ setState;
()
};
let getCount = fetchAndUpdate "count";
let incrementCount = fetchAndUpdate "increment";
let decrementCount = fetchAndUpdate "decrement";
};
module GroupCounter = {
include ReactRe.Component.Stateful.InstanceVars;
let name = "GroupCounter";
type props = unit;
/** state */
type state = {count: int};
let getInitialState _ => {count: 0};
/** instanceVars */
type instanceVars = {mutable intervalID: option ReasonJs.intervalId};
let getInstanceVars () => {intervalID: None};
/** count setting callback */
let countSetter setState str => setState (fun _ => {count: int_of_string str});
/** lifecycle methods */
let componentDidMount {instanceVars, setState} => {
let intervalID =
ReasonJs.setInterval (fun () => CounterAPI.getCount (countSetter setState)) 500;
instanceVars.intervalID = Some intervalID;
None
};
let componentWillUnmount {instanceVars} =>
switch instanceVars.intervalID {
| None => ()
| Some id => ReasonJs.clearInterval id
};
/** event handlers */
let handleIncrement {setState} _ => {
CounterAPI.incrementCount (countSetter setState);
None
};
let handleDecrement {setState} _ => {
CounterAPI.decrementCount (countSetter setState);
None
};
/** render */
let render {state, updater} =>
<div>
<h1> (ReactRe.stringToElement (string_of_int state.count)) </h1>
<button onClick=(updater handleIncrement)> (ReactRe.stringToElement "Increment") </button>
<button onClick=(updater handleDecrement)> (ReactRe.stringToElement "Decrement") </button>
</div>;
};
include ReactRe.CreateComponent GroupCounter;
let createElement = wrapProps ();
let () =
ReactDOMRe.render (createElement children::[] ()) (ReasonJs.Document.getElementById "index");
module Input = {
include ReactRe.Component.Stateful;
let name = "Input";
type state = {display: string};
type props = unit;
let getInitialState _ => {display: "Please type something."};
/** input handler */
let handleInputChange _ event => {
let inputStr = ReasonJs.Document.value event##target;
/** pattern matching example */
let displayStr =
switch inputStr {
| "" => "Please type something."
| " " => "A space is not something!"
| _ => "input: " ^ inputStr
};
Some {display: displayStr}
};
/** render */
let render {state, updater} =>
<div>
<input onChange=(updater handleInputChange) />
<h1> (ReactRe.stringToElement state.display) </h1>
</div>;
};
include ReactRe.CreateComponent Input;
let createElement = wrapProps ();
let () =
ReactDOMRe.render (createElement children::[] ()) (ReasonJs.Document.getElementById "index");
module MessageAdapter = {
let submitMessage message => {
let baseUrl = "https://rehydrate-workshop-board-server-vfxanxldvd.now.sh/message/";
let _ = ReasonJs.fetch (baseUrl ^ message);
()
};
};
module Input2 = {
include ReactRe.Component.Stateful;
open MessageAdapter;
let name = "Input2";
type state = {input: string};
type props = unit;
let getInitialState _ => {input: ""};
/** input change handler */
let handleInputChange _ event => Some {input: ReasonJs.Document.value event##target};
/** key down handler */
let handleKeyDown {state, updater} event => {
let clearInput = updater (fun _ _ => Some {input: ""});
switch event##keyCode {
/* pattern match for enter key */
| 13 =>
submitMessage state.input;
clearInput ()
| _ => ()
};
None
};
/** render */
let render {state, updater} =>
<div>
<input
onChange=(updater handleInputChange)
onKeyDown=(updater handleKeyDown)
value=state.input
/>
<h1> (ReactRe.stringToElement state.input) </h1>
</div>;
};
include ReactRe.CreateComponent Input2;
let createElement = wrapProps ();
let () =
ReactDOMRe.render (createElement children::[] ()) (ReasonJs.Document.getElementById "index");
module Page = {
module Foo = {
include ReactRe.Component;
let name = "Foo";
type props = {message: string};
let render {props} => <div> (ReactRe.stringToElement props.message) </div>;
};
include ReactRe.CreateComponent Foo;
let createElement ::message => wrapProps {message: message};
};
let () = ReactDOMRe.render <Page message="hello" /> (ReasonJs.Document.getElementById "index");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment