Can I use ReasonML context in js components?

Hello, I have a simple context written in ReasonML in file TestContext.re:

module Config = {
  type t = {
    test: string,
    setTest: string => unit,
  };
  let defaultValue = { test: "TEST", setTest: _ => ()};
};

module Ctx = Infra_Context.Make(Config);

module Provider = {
  [@react.component]
  let make = (~children) => {
    let (test, setTest) = React.useState(() => "TEST");

    <Ctx.Provider
      value={ test, setTest : t => setTest(_ => t)}>
      children
    </Ctx.Provider>;
  };
};

let use = Ctx.use;


module type Config = {
  type t;
  let defaultValue: t;
};

module Make = (Config: Config) => {
  let ctx = React.createContext(Config.defaultValue);

  module Provider = {
    [@bs.obj]
    external makeProps:
      (~key: string=?, ~value: Config.t, ~children: React.element, unit) =>
      {
        .
        "value": Config.t,
        "children": React.element,
      } =
      "";
    let make = React.Context.provider(ctx);
  };

  let use = () => React.useContext(ctx);
};

I would like to use it in my js components. What I do is:

  1. Convert .re files to .bs.js files using bsb -make-world
  2. In my js component:
import {use as useTestContext} from 'TestContext.bs'

const Test = () => {
  const {test} = useTestContext()
}

as a result I am able to get initial values from context state, but whenever context is updated, context values are not updated in my js component. As a result, I do always receive initial values. At the same time, in .re components everything works fine. How can I make it work properly? Thanks in advance.

Workaround:

Since I did not find a way to use context written in ReasonML in my js components, I have created another context in js and imported it in my ReasonML component. Then, state manipulation on ReasonML side worked properly - I was able to update context state in ReasonML code and my js components did receive updated values.

Interesting. Do they share same tree, i.e. are the JS components also children of the provider?

Unrelated, but if you find the as useFoo cumbersome, you could always alias it within the module. let useFoo = use.

EDIT: And perhaps as a general aside, it’s all just JS in the end, so apart from e.g. bundling issues there shouldn’t really be a difference.