Skip to content

Instantly share code, notes, and snippets.

@saitonakamura
Created December 19, 2018 16:22
Show Gist options
  • Save saitonakamura/25d54fcff4796f136ba3eff10faabd60 to your computer and use it in GitHub Desktop.
Save saitonakamura/25d54fcff4796f136ba3eff10faabd60 to your computer and use it in GitHub Desktop.
open Js.Promise;
type state('a) = {
data: option('a),
isLoading: bool,
};
type action('a) =
| Load
| Loaded('a);
let component = ReasonReact.reducerComponent("Loadable");
let make =
(
~promise: unit => Js.Promise.t('a),
children: 'a => ReasonReact.reactElement,
) => {
...component,
initialState: () => {data: None, isLoading: false},
didMount: self => self.send(Load),
reducer: (action: action('a), state: state('a)) =>
switch (action) {
| Load =>
ReasonReact.UpdateWithSideEffects(
{...state, isLoading: true},
self =>
promise()
|> then_(data => self.send(Loaded(data)) |> resolve)
|> ignore,
)
| Loaded(data) =>
ReasonReact.Update({data: Some(data), isLoading: false})
},
render: self =>
switch (self.state) {
| {isLoading: true} => <div> {ReasonReact.string("Loading...")} </div>
| {data: None} => <div> {ReasonReact.string("No data")} </div>
| {data: Some(data)} => <div> {children(data)} </div>
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment