Accessing displayName of ReasonReact component

reasonreact

#1

Hey y’all, does anyone know if there’s a way to access the displayName property of a ReasonReact component? I was looking to automate a styleguide I’m building for a application, and I was hoping to pull the name directly from the component itself rather than have to duplicate the name.

To be honest, I’m not sure if this is the right way to approach this problem either, so I’m happy to hear other examples of how I could approach it!

To give you an example of what I’m trying to do, I have this Strings.re where I’m defining the text for my app. I currently have something like this:

  module Wrapper = {
    let title = "Wrapper";
    let description = "a general purpose wrapper that applies a max-width and some padding. Meant to be used around the whole page";
}
...

But would like to have something like this:

 module Wrapper = {
    let title = Wrapper.displayName;
    let description = "a general purpose wrapper that applies a max-width and some padding. Meant to be used around the whole page";
}

#2

You could, for example, define displayName and description variables right in the component’s module, and access them in the Strings module. Although at that point I’m not sure if Strings module would be useful anymore.

/* components/Wrapper.re */
[@react.component]
let make = () => React.string("Your component");

let displayName = "Wrapper";
let description = "A general purpose wrapper that applies a max-width and some padding. Meant to be used around the whole page";

React.setDisplayName(make, displayName);

/* Strings.re */
module Styleguide = {
  let title = "Styleguide";

  module Wrapper = {
    let title = Wrapper.displayName;
    let description = Wrapper.description;
  };
}

If you want to access the name of the component programmatically, I don’t think there’s an official way to do that.
But, it could be accomplished using a custom binding with [@bs.get] and [@bs.return nullable]:

[@bs.get] [@bs.return nullable]
external displayName: React.component('props) => option(string) = "name";

let name = displayName(Wrapper.make); /* returns Some("Wrapper") */
Js.log(name);

This would effectively compile to something like:

import { make } from "components/Wrapper.bs.js"

console.log(make.name);