|
|
@@ -0,0 +1,78 @@ |
|
|
// hey you two! Ignore these externals for now. They're just for illustration |
|
|
// purposes. I just copy pasted the Js code from |
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest |
|
|
// and translated it to Reason |
|
|
|
|
|
type request; |
|
|
type response; |
|
|
[@bs.new] external makeXMLHttpRequest: unit => request = "XMLHttpRequest"; |
|
|
[@bs.send] external addEventListener: (request, string, unit => unit) => unit = "addEventListener"; |
|
|
[@bs.get] external response: request => response = "response"; |
|
|
[@bs.send] external open_: (request, string, string) => unit = "open"; |
|
|
[@bs.send] external send: request => unit = "send"; |
|
|
[@bs.send] external abort: request => unit = "abort"; |
|
|
|
|
|
[@bs.scope "JSON"][@bs.val] external parseResponse: response => {. "message": array(string)} = "parse"; |
|
|
|
|
|
// ================ alright |
|
|
|
|
|
type state = |
|
|
| LoadingDogs |
|
|
| ErrorFetchingDogs |
|
|
| LoadedDogs(array(string)); |
|
|
|
|
|
[@react.component] |
|
|
let make = () => { |
|
|
let (state, setState) = React.useState(() => LoadingDogs); |
|
|
|
|
|
// Notice that instead of `useEffect`, we have `useEffect0`. See |
|
|
// reasonml.github.io/reason-react/docs/en/components#hooks for more info |
|
|
React.useEffect0(() => { |
|
|
let request = makeXMLHttpRequest() |
|
|
request->addEventListener("load", () => { |
|
|
setState(_previousState => LoadedDogs((request->response->parseResponse)##message)); |
|
|
}) |
|
|
request->addEventListener("error", () => { |
|
|
setState(_previousState => ErrorFetchingDogs); |
|
|
}) |
|
|
request->open_("GET", "https://dog.ceo/api/breeds/image/random/3"); |
|
|
request->send |
|
|
|
|
|
// the return value is called by React's useEffect when the component unmounts |
|
|
Some(() => { |
|
|
request->abort |
|
|
}) |
|
|
}); |
|
|
|
|
|
<div |
|
|
style={ReactDOMRe.Style.make( |
|
|
~height="120px", |
|
|
~display="flex", |
|
|
~alignItems="center", |
|
|
~justifyContent="center", |
|
|
(), |
|
|
)}> |
|
|
{switch (state) { |
|
|
| ErrorFetchingDogs => React.string("An error occurred!") |
|
|
| LoadingDogs => React.string("Loading...") |
|
|
| LoadedDogs(dogs) => |
|
|
dogs |
|
|
->Belt.Array.mapWithIndex((i, dog) => { |
|
|
let imageStyle = |
|
|
ReactDOMRe.Style.make( |
|
|
~height="120px", |
|
|
~width="100%", |
|
|
~marginRight=i === Js.Array.length(dogs) - 1 ? "0px" : "8px", |
|
|
~borderRadius="8px", |
|
|
~boxShadow="0px 4px 16px rgb(200, 200, 200)", |
|
|
~backgroundSize="cover", |
|
|
~backgroundImage={j|url($dog)|j}, |
|
|
~backgroundPosition="center", |
|
|
(), |
|
|
); |
|
|
<div key=dog style=imageStyle />; |
|
|
}) |
|
|
->React.array |
|
|
}} |
|
|
</div>; |
|
|
}; |