diff --git a/misc_docs/syntax/decorator_react_component_with_props.mdx b/misc_docs/syntax/decorator_react_component_with_props.mdx
new file mode 100644
index 000000000..689b32e76
--- /dev/null
+++ b/misc_docs/syntax/decorator_react_component_with_props.mdx
@@ -0,0 +1,51 @@
+---
+id: "react-component-with-props-decorator"
+keywords: ["react", "component", "props", "decorator"]
+name: "@react.componentWithProps"
+summary: "This is the `@react.componentWithProps` decorator."
+category: "decorators"
+---
+
+The `@react.componentWithProps` decorator is used to annotate functions that are [React](/docs/react/latest/elements-and-jsx) components which take in a record type as prop.
+This decorator will ensure your component gets an uppercased name.
+
+
+> **Note**
+> The `@react.componentWithProps` decorator requires the [react-jsx or jsx config](/docs/react/latest/installation) to be set in your `rescript.json` to enable the required React transformations.
+
+### Example
+
+
+
+```res
+module Hey = {
+ type props = {
+ name: string,
+ }
+
+ @react.componentWithProps
+ let make = (props: props) => {
+
+ }
+}
+```
+
+```js
+import * as JsxRuntime from "react/jsx-runtime";
+
+function Playground$Hey(props) {
+ return JsxRuntime.jsx("button", {
+ children: "Hello " + props.name + "!"
+ });
+}
+
+let Hey = {
+ make: Playground$Hey
+};
+```
+
+
+
+### References
+
+* [React Components](/docs/react/latest/components-and-props)
diff --git a/pages/docs/react/latest/components-and-props.mdx b/pages/docs/react/latest/components-and-props.mdx
index 58ddd7750..fc3ab0d87 100644
--- a/pages/docs/react/latest/components-and-props.mdx
+++ b/pages/docs/react/latest/components-and-props.mdx
@@ -39,7 +39,9 @@ let make = () => {
import * as React from "react";
function Greeting(props) {
- return React.createElement("div", undefined, "Hello ReScripters!");
+ return JsxRuntime.jsx("div", {
+ children: "Hello ReScripters!"
+ });
}
var make = Greeting;
@@ -51,7 +53,7 @@ var make = Greeting;
We've created a `Greeting.res` file that contains a `make` function that doesn't receive any props (the function doesn't receive any parameters), and returns a `React.element` that represents `
Hello ReScripters!
` in the rendered DOM.
-You can also see in the the JS output that the function we created was directly translated into the pure JS version of a ReactJS component. Note how a `
` transforms into a `React.createElement("div",...)` call in JavaScript.
+You can also see in the the JS output that the function we created was directly translated into the pure JS version of a ReactJS component. Note how a `
` transforms into a `JsxRuntime.jsx("div",...)` call in JavaScript.
## Defining Props
@@ -272,6 +274,69 @@ The best way to approach this kind of issue is by using props instead of childre
**The best use-case for `children` is to pass down `React.element`s without any semantic order or implementation details!**
+## @react decorators
+
+You might've wondered what `@react.component` actually does.
+It's a decorator that tells the ReScript compiler to treat the function as a React component, transforming it at the syntax level.
+
+In JavaScript, a React component is just a function that takes props (an object) and returns JSX. In ReScript, props are typically represented as a record type.
+The `@react.component` decorator automatically generates that record type and wraps the function for you—so you don't have to.
+
+```res
+// Counter.res
+
+@react.component
+let make = (~title, ~count) => {
+
{React.string(title)} {React.int(count)}
+}
+
+// This is equivalent to writing:
+
+type props = {title: string, count: int}
+
+let \"Counter" = ({title, count}: props) => {
+
{React.string(title)} {React.int(count)}
+}
+```
+
+However, writing it manually like this means you lose the `make` function name, which prevents JSX from working as expected when using the component elsewhere.
+
+Having an uppercased function name also helps distinguish React components from regular functions in [React DevTools](https://react.dev/learn/react-developer-tools).
+
+If you prefer defining your own props record, you can use `@react.componentWithProps`. This gives you full control over the props type while still generating a proper uppercased component.
+
+
+
+```res
+// Counter.res
+type props = {title: string, count: int}
+
+@react.componentWithProps
+let make = (props: props) => {
+
+}
+```
+
+```js
+import * as JsxRuntime from "react/jsx-runtime";
+
+function Counter(props) {
+ return JsxRuntime.jsxs("h1", {
+ children: [
+ props.title,
+ props.count
+ ]
+ });
+}
+
+let make = Counter;
+```
+
+
+
## Props & Type Inference
The ReScript type system is really good at inferring the prop types just by looking at its prop usage.
@@ -405,7 +470,7 @@ let content =
## Component Naming
-Because components are actually a pair of functions, they have to belong to a module to be used in JSX. It makes sense to use these modules for identification purposes as well. `@react.component` automatically adds the name for you based on the module you are in.
+Because components are actually a pair of functions, they have to belong to a module to be used in JSX. It makes sense to use these modules for identification purposes as well. `@react.component` or `@react.componentWithProps` automatically adds the name for you based on the module you are in.
```res