Skip to content

Commit

Permalink
Bind React.act and React.actAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
davesnx committed Nov 25, 2024
1 parent 7aaef3e commit 5171ac5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/React.re
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,10 @@ external startTransition: ([@mel.uncurry] (unit => unit)) => unit =
external useDebugValue: ('value, ~format: 'value => string=?, unit) => unit =
"useDebugValue";

[@mel.module "react"] external act: (unit => unit) => unit = "act";
[@mel.module "react"]
external actAsync: (unit => Js.Promise.t(unit)) => unit = "act";

module Experimental = {
/* This module is used to bind to APIs for future versions of React. There is no guarantee of backwards compatibility or stability. */
/* https://react.dev/reference/react/use */
Expand Down
4 changes: 4 additions & 0 deletions src/React.rei
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ external startTransition: ([@mel.uncurry] (unit => unit)) => unit =
external useTransition: unit => (bool, callback(callback(unit, unit), unit)) =
"useTransition";

[@mel.module "react"] external act: (unit => unit) => unit = "act";
[@mel.module "react"]
external actAsync: (unit => Js.Promise.t(unit)) => unit = "act";

module Experimental: {
/* This module is used to bind to APIs for future versions of React. There is no guarantee of backwards compatibility or stability. */
[@mel.module "react"] external usePromise: Js.Promise.t('a) => 'a = "use";
Expand Down
32 changes: 32 additions & 0 deletions test/React__test.re
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,38 @@ describe("React", () => {
expect(image->getAttribute("src"))->toEqual(Some("https://foo.png"));
});

test("React.act", () => {
module Counter = {
[@react.component]
let make = () => {
let (count, setCount) = React.useState(() => 0);

<div>
<button role="Increment" onClick={_ => setCount(prev => prev + 1)}>
{React.string("Increment")}
</button>
<span role="counter"> {React.string(string_of_int(count))} </span>
</div>;
};
};

let containerRef: ref(Js.nullable(ReactTestingLibrary.renderResult)) =
ref(Js.Nullable.null);

React.act(() => {
let container = ReactTestingLibrary.render(<Counter />);
let button = getByRole("Increment", container);
FireEvent.click(button);
containerRef.contents = Js.Nullable.return(container);
});

switch (Js.Nullable.toOption(containerRef.contents)) {
| Some(container) =>
expect(getByRole("counter", container)->innerHTML)->toBe("1")
| None => failwith("Container is null")
};
});

test("ErrorBoundary + Suspense", () => {
[%mel.raw "console.error = () => {}"] |> ignore;

Expand Down

0 comments on commit 5171ac5

Please sign in to comment.