Skip to content

Instantly share code, notes, and snippets.

@yhsiang
Created December 6, 2017 05:39
Show Gist options
  • Save yhsiang/b103e143aaae532e022c9af536cf3aef to your computer and use it in GitHub Desktop.
Save yhsiang/b103e143aaae532e022c9af536cf3aef to your computer and use it in GitHub Desktop.
ReasonReact Posts Component
type post = {
userId: int,
id: int,
title: string,
body: string
};
type posts = list(post);
type state = {
posts: posts
};
type action =
| Loaded(posts);
let component = ReasonReact.reducerComponent("Posts");
let str = ReasonReact.stringToElement;
let decode = json => {
Json.Decode.{
userId: json |> field("userId", int),
id: json |> field("id", int),
title: json |> field("title", string),
body: json |> field("body", string)
};
};
let fetchData = () =>
Js.Promise.(
Fetch.fetch("https://jsonplaceholder.typicode.com/posts")
|> then_(Fetch.Response.json)
|> then_((json) => {
let opt = Js.Json.decodeArray(json);
let posts = switch opt {
| None => [||]
| Some(arr) => Array.map(decode, arr)
};
resolve(posts);
})
);
let make = (_c) => {
...component,
initialState: () => {posts: []},
didMount: (self) => {
fetchData()
|> Js.Promise.then_(posts => {
self.reduce(_ev => Loaded(Array.to_list(posts)))();
Js.Promise.resolve();
})
|> ignore;
ReasonReact.NoUpdate;
},
reducer: (action, {posts}) =>
switch action {
| Loaded(data) => ReasonReact.Update({ posts: List.concat([data, posts]) })
},
render: (s) => {
let items = List.map(it => <li>(str(it.title))</li>, s.state.posts);
<ul>(ReasonReact.arrayToElement(Array.of_list(items)))</ul>
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment