Skip to content

Instantly share code, notes, and snippets.

@SekibOmazic
Forked from busypeoples/UIPattern.re
Created October 21, 2017 15:34
Show Gist options
  • Save SekibOmazic/b207a424e9768401a53b7cfbb0cd0c9d to your computer and use it in GitHub Desktop.
Save SekibOmazic/b207a424e9768401a53b7cfbb0cd0c9d to your computer and use it in GitHub Desktop.
Slaying a UI Anti Pattern in ReasonML
/*
Slaying a UI Anti Pattern in ReasonML
Based on Kris Jenkins original writing.
http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html
*/
type remoteData 'e 'a =
| NotAsked
| Loading
| Failure 'e
| Success 'a;
type user = {
id: int,
name: string
};
type state = {data: remoteData string (list user)};
let se = ReasonReact.stringToElement;
let fetchData () => Success [{id: 1, name: "foo"}, {id: 2, name: "bar"}];
let component = ReasonReact.reducerComponent "View";
let displayData data =>
ReasonReact.arrayToElement (
Array.of_list (
List.map
(fun {id, name} => <div key=(string_of_int id)> (se name) </div>) data
)
);
type action = remoteData string (list user);
/* ReasonReact.NoUpdate */
let make _ => {
...component,
initialState: fun () => {data: NotAsked},
reducer: fun action state =>
switch action {
| NotAsked => ReasonReact.NoUpdate /* If you skip a possible case, you will get a warning not an error */
| Loading => ReasonReact.Update {...state, data: Loading}
| Failure msg => ReasonReact.Update {...state, data: Failure msg}
| Success data => ReasonReact.Update {...state, data: Success data}
},
render: fun {state, reduce} =>
<div>
(
switch state.data {
| NotAsked =>
<div>
(se "Not Data Fetched Yet!")
<button
onClick=(
fun _evt => {
Js.Global.setTimeout (reduce (fun () => Loading)) 10;
Js.Global.setTimeout (reduce fetchData) 2000;
ignore ()
}
)>
(se "Fetch Data!")
</button>
</div>
| Loading => <div> (se "Loading Data...") </div>
| Failure msg => <div> (se ("Some Error: " ^ msg)) </div>
| Success data => <div> (se "Loaded Users") (displayData data) </div>
}
)
</div>
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment