-
-
Save lanqy/47a975e178690e1f62ff955d98d1911e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let str = ReasonReact.string; | |
let el = ReasonReact.element; | |
let arr = ReasonReact.array; | |
module Dashboard = { | |
let component = ReasonReact.statelessComponent("Dashboard"); | |
let make = _children => { | |
...component, | |
render: _self => <div> <h2> (str("Dashboard")) </h2> </div>, | |
}; | |
}; | |
module Users = { | |
let component = ReasonReact.statelessComponent("Users"); | |
let make = _children => { | |
...component, | |
render: _self => <div> <h2> (str("Users")) </h2> </div>, | |
}; | |
}; | |
module User = { | |
let component = ReasonReact.statelessComponent("User"); | |
let make = (~id, _children) => { | |
...component, | |
render: _self => | |
<div> <h2> (str("User : " ++ string_of_int(id))) </h2> </div>, | |
}; | |
}; | |
module type Config = { | |
type route; | |
let toUrl: route => string; | |
let toRoute: ReasonReact.Router.url => route; | |
}; | |
module CreateRouter = (Config: Config) => { | |
type route = Config.route; | |
type renderProps = { | |
updateRoute: route => unit, | |
route, | |
}; | |
type state = {route}; | |
type action = | |
| UpdateRoute(route); | |
let component = ReasonReact.reducerComponent("Router"); | |
let make = (~render, _children) => { | |
...component, | |
initialState: () => { | |
route: ReasonReact.Router.dangerouslyGetInitialUrl() |> Config.toRoute, | |
}, | |
subscriptions: self => [ | |
Sub( | |
() => | |
ReasonReact.Router.watchUrl(url => | |
self.send(UpdateRoute(Config.toRoute(url))) | |
), | |
ReasonReact.Router.unwatchUrl, | |
), | |
], | |
reducer: (action, _state) => | |
switch (action) { | |
| UpdateRoute(route) => ReasonReact.Update({route: route}) | |
}, | |
render: self => | |
render({ | |
updateRoute: route => self.send(UpdateRoute(route)), | |
route: self.state.route, | |
}), | |
}; | |
}; | |
type page = | |
| Dashboard | |
| Users | |
| User(int); | |
module Config = { | |
type route = page; | |
let toRoute = (url: ReasonReact.Router.url) => | |
switch (url.path) { | |
| ["user", id] => User(int_of_string(id)) | |
| ["users"] => Users | |
| _ => Dashboard | |
}; | |
let toUrl = route => | |
switch (route) { | |
| User(id) => "/user/" ++ string_of_int(id) | |
| Users => "/users" | |
| Dashboard => "/" | |
}; | |
}; | |
module Router = CreateRouter(Config); | |
module Link = { | |
let component = ReasonReact.statelessComponent("Link"); | |
let make = (~route, ~toUrl, ~render, _children) => { | |
...component, | |
render: _self => { | |
let href = toUrl(route); | |
let onClick = e => { | |
ReactEventRe.Mouse.preventDefault(e); | |
ReasonReact.Router.push(href); | |
}; | |
<a href onClick> (render()) </a>; | |
}, | |
}; | |
}; | |
module App = { | |
let component = ReasonReact.statelessComponent("App"); | |
let make = _self => { | |
...component, | |
render: _self => | |
<div> | |
<Router | |
render=( | |
({route}) => | |
switch (route) { | |
| Dashboard => <Dashboard /> | |
| User(id) => <User id /> | |
| Users => <Users /> | |
} | |
) | |
/> | |
<Link route=Users toUrl=Config.toUrl render=(() => str("Users!")) /> | |
<Link | |
route=Dashboard | |
toUrl=Config.toUrl | |
render=(() => str("Dashboard!")) | |
/> | |
</div>, | |
}; | |
}; | |
ReactDOMRe.renderToElementWithId(<App />, "root"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment