Skip to content

Instantly share code, notes, and snippets.

@dotfold
Last active May 17, 2018 22:01
Show Gist options
  • Save dotfold/b44df0280a6b7c04ff70b06cd7948023 to your computer and use it in GitHub Desktop.
Save dotfold/b44df0280a6b7c04ff70b06cd7948023 to your computer and use it in GitHub Desktop.
ReasonML Link and Router components that integrate with the built in router
/* this doesn't work because of the null renderer */
module Redirect {
let component = ReasonReact.statelessComponent("Redirect");
let make = (~_to, _children) => {
...component,
didMount: _self => {
ReasonReact.Router.push(_to)
},
render: _self => ReasonReact.null
}
};
/* taken from the razzle examples repo */
type action =
| UpdateRoute(ReasonReact.Router.url);
type state = ReasonReact.Router.url;
/* copied from ReasonReact */
let urlToUrlList = url =>
switch url {
| ""
| "/" => []
| _ =>
/* remove the preceeding /, which every pathname seems to have */
let raw = Js.String.sliceToEnd(~from=1, url);
/* remove the trailing /, which some pathnames might have. Ugh */
let raw =
switch (Js.String.get(raw, Js.String.length(raw) - 1)) {
| "/" => Js.String.slice(~from=0, ~to_=-1, raw)
| _ => raw
};
raw |> Js.String.split("/") |> Array.to_list;
};
let component = ReasonReact.reducerComponent("Router");
let make:
(~initialUrl: option(string), 'a) => ReasonReact.component(state, _, action) =
(~initialUrl, children) => {
...component,
initialState: () =>
switch initialUrl {
| Some(url) => {path: urlToUrlList(url), hash: "", search: ""}
| None => ReasonReact.Router.dangerouslyGetInitialUrl()
},
reducer: (action, _state) =>
switch action {
| UpdateRoute(url) => ReasonReact.Update(url)
},
subscriptions: ({send}) => [
Sub(
() => ReasonReact.Router.watchUrl(url => send(UpdateRoute(url))),
ReasonReact.Router.unwatchUrl
)
],
render: ({state}) => children(state)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment