diff --git a/CHANGELOG.md b/CHANGELOG.md index d3e87162f2..467ff9b707 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ - Fix `--create-sourcedirs` generation with for a single project. https://github.com/rescript-lang/rescript/pull/7671 - Fix rewatch not recompiling on changes under windows. https://github.com/rescript-lang/rescript/pull/7690 - Fix locations of regex literals. https://github.com/rescript-lang/rescript/pull/7683 +- Fix async React component compilation. https://github.com/rescript-lang/rescript/pull/7704 # 12.0.0-beta.2 diff --git a/compiler/syntax/src/jsx_common.ml b/compiler/syntax/src/jsx_common.ml index 6937bd14d0..a48cf11bc9 100644 --- a/compiler/syntax/src/jsx_common.ml +++ b/compiler/syntax/src/jsx_common.ml @@ -53,10 +53,6 @@ let async_component ~async expr = if async then let open Ast_helper in Exp.apply - (Exp.ident - { - loc = Location.none; - txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); - }) + (Exp.ident {loc = Location.none; txt = Ldot (Lident "Jsx", "promise")}) [(Nolabel, expr)] else expr diff --git a/runtime/Jsx.res b/runtime/Jsx.res index 05442ad822..7cc7ade95c 100644 --- a/runtime/Jsx.res +++ b/runtime/Jsx.res @@ -30,8 +30,8 @@ type element external float: float => element = "%identity" external int: int => element = "%identity" external string: string => element = "%identity" - external array: array => element = "%identity" +external promise: promise => element = "%identity" type componentLike<'props, 'return> = 'props => 'return type component<'props> = componentLike<'props, element> diff --git a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt index 37df951e28..66441d1f69 100644 --- a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt @@ -9,7 +9,7 @@ module C0 = { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } let make = { - let \"AsyncAwait$C0" = (props: props<_>) => JsxPPXReactSupport.asyncComponent(make(props)) + let \"AsyncAwait$C0" = (props: props<_>) => Jsx.promise(make(props)) \"AsyncAwait$C0" } @@ -26,7 +26,7 @@ module C1 = { } } let make = { - let \"AsyncAwait$C1" = (props: props<_>) => JsxPPXReactSupport.asyncComponent(make(props)) + let \"AsyncAwait$C1" = (props: props<_>) => Jsx.promise(make(props)) \"AsyncAwait$C1" } diff --git a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt index b1f4205c36..72072f8985 100644 --- a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt @@ -45,8 +45,7 @@ module V4A5 = { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } let make = { - let \"SharedPropsWithProps$V4A5" = (props: props<_>) => - JsxPPXReactSupport.asyncComponent(make(props)) + let \"SharedPropsWithProps$V4A5" = (props: props<_>) => Jsx.promise(make(props)) \"SharedPropsWithProps$V4A5" } } @@ -60,8 +59,7 @@ module V4A6 = { } } let make = { - let \"SharedPropsWithProps$V4A6" = (props: props<_>) => - JsxPPXReactSupport.asyncComponent(make(props)) + let \"SharedPropsWithProps$V4A6" = (props: props<_>) => Jsx.promise(make(props)) \"SharedPropsWithProps$V4A6" } } diff --git a/tests/tests/src/async_jsx.mjs b/tests/tests/src/async_jsx.mjs new file mode 100644 index 0000000000..795c65b52c --- /dev/null +++ b/tests/tests/src/async_jsx.mjs @@ -0,0 +1,41 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as JsxRuntime from "react/jsx-runtime"; + +function getNow() { + return new Promise((res, param) => { + setTimeout(() => res(new Date()), 1000); + }); +} + +async function make(param) { + let now = await getNow(); + return
+

+ {now.toLocaleString()} +

+
; +} + +let Async_jsx$Foo = make; + +let Foo = { + make: Async_jsx$Foo +}; + +function Async_jsx$Bar(props) { + return
+ +
; +} + +let Bar = { + make: Async_jsx$Bar +}; + +export { + getNow, + Foo, + Bar, +} +/* react/jsx-runtime Not a pure module */ diff --git a/tests/tests/src/async_jsx.res b/tests/tests/src/async_jsx.res new file mode 100644 index 0000000000..277e357164 --- /dev/null +++ b/tests/tests/src/async_jsx.res @@ -0,0 +1,30 @@ +@@config({ + flags: ["-bs-jsx", "4", "-bs-jsx-preserve"], +}) + +let getNow = () => { + Promise.make((res, _) => { + setTimeout(() => { + res(Date.make()) + }, 1000)->ignore + }) +} + +module Foo = { + @react.component + let make = async () => { + let now = await getNow() +
+

{React.string(now->Date.toLocaleString)}

+
+ } +} + +module Bar = { + @react.component + let make = () => { +
+ +
+ } +}