Hm, I usually do a combination of a router component and variants. As a quick example:
Router.re
type route =
| Dashboard
| Licenses
| Updates(option(string));
let getRouteByUrl = (url: ReasonReact.Router.url) => {
let path = url.hash |> Js.String.split("/");
switch (path) {
| [|""|]
| [|"", ""|]
| [|"", "dashboard"|] => Dashboard
| [|"", "licenses"|] => Licenses
| [|"", "updates"|] => Updates(None)
| [|"", "updates", updateId|] => Updates(Some(updateId))
};
};
let component = ReasonReact.reducerComponent("Router");
let make = children => {
...component,
initialState: () =>
ReasonReact.Router.dangerouslyGetInitialUrl()->getRouteByUrl,
reducer: (action: route, _state: route) => ReasonReact.Update(action),
didMount: ({send, onUnmount}) => {
let interpretUrl = (url: ReasonReact.Router.url) =>
send(url->getRouteByUrl);
interpretUrl(ReasonReact.Router.dangerouslyGetInitialUrl());
let watcherId = ReasonReact.Router.watchUrl(interpretUrl);
onUnmount(() => watcherId->ReasonReact.Router.unwatchUrl);
},
render: ({state}) => children(state),
};
Layout.re
/* ... */
<div className=classes.subContent>
(
switch (route) {
| Dashboard => <Dashboard_Dashboard />
| Licenses => <Dashboard_Licenses />
| MailSettings => <Dashboard_MailSettings />
| Updates(updateId) =>
<Dashboard_Updates updateId />
| _ =>
"Route not implemented"->ReasonReact.string
}
)
</div>
/* ... */
Just as an example. The variants / reducer pattern makes it so that you always know which item is active. Or did I get you wrong in that you wish to make this menu more dynamic, like from a database?