Skip to content

Make ReasonReactRouter.useUrl return ~serverUrl or throw #123

@purefunctor

Description

@purefunctor

Hi, this is a really awesome library! I'm having fun re-learning OCaml and ReasonML with it.

Based on the documentation for ReasonReactRouter.useUrl:

/** hook for watching url changes.
 * serverUrl is used for ssr. it allows you to specify the url without relying on browser apis existing/working as expected
 */

This is reflected in the implementation where if the serverUrl is passed, it just returns that--otherwise, it calls into JS in order to obtain the URL (which is not possible in a server context).

In server-reason-react, useUrl returns an empty url and completely ignores serverUrl. If used in a shared component, routing silently fails and the [] gets matched every time:

module App = {
  [@react.component]
  let make = (~serverUrl: option(ReasonReactRouter.url)=?) => {
    let url = ReasonReactRouter.useUrl(~serverUrl?, ());
    switch (url.path) {
    | [] => <div> {React.string("Index!")} </div>
    | [name] => <Counter name />
    | _ => <div> {React.string("Not Found!")} </div>
    };
  };
};

The workaround I came up with is:

module App = {
  [@react.component]
  let make = (~serverUrl: option(ReasonReactRouter.url)=?) => {
    let url =
      switch%platform (Runtime.platform) {
      | Client => ReasonReactRouter.useUrl(~serverUrl?, ())
      | Server =>
        switch (serverUrl) {
        | Some(serverUrl) => serverUrl
        | None => raise(Invalid_argument("Server component needs URL!"))
        }
      };
  
    switch (url.path) {
    | [] => <div> {React.string("Index!")} </div>
    | [name] => <Counter name />
    | _ => <div> {React.string("Not Found!")} </div>
    };
  };
};

Alternatively, having separate implementations as suggested by the code-structure docs is another reasonable solution.

What do you think of defining useUrl as the following?

let useUrl ?(serverUrl : ReasonReactRouter.url option) (_ : unit) =
  match serverUrl with
  | Some serverUrl -> serverUrl
  | None -> raise (Invalid_argument "Must provide serverUrl")

I could also write the PR for it--would be cool as a first contribution to the ecosystem 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions