Skip to content

Commit c171edc

Browse files
mununkicknitt
andauthored
Update React page (#593)
* add React v0.10.0 page * remove migration from react latest and - add jsx v3 and v4 * update introduction * update installation * rename to migrate-from-v3 * add migrate from v3 page * add toc for extensions of props page * update element and jsx page * update rendering-elements page * update components and props page * update context page * update hooks-context page * update beyond jsx page * update forwarding-refs page * update extensions of props page * fix beyond jsx page * remove react.component from expanded * remove react.component * add extensions of props page * Update pages/docs/react/latest/installation.mdx Co-authored-by: Christoph Knittel <[email protected]> * remove the flow support of gentype * Update pages/docs/react/latest/beyond-jsx.mdx Co-authored-by: Christoph Knittel <[email protected]> * Update pages/docs/react/latest/beyond-jsx.mdx Co-authored-by: Christoph Knittel <[email protected]> * Update pages/docs/react/latest/migrate-from-v3.mdx Co-authored-by: Christoph Knittel <[email protected]> * Update pages/docs/react/latest/migrate-from-v3.mdx Co-authored-by: Christoph Knittel <[email protected]> * add make function name comment * Update pages/docs/react/latest/migrate-from-v3.mdx Co-authored-by: Christoph Knittel <[email protected]> * add automatic codes Co-authored-by: Christoph Knittel <[email protected]>
1 parent 7a2c329 commit c171edc

40 files changed

+4763
-313
lines changed

data/sidebar_react_latest.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"Overview": [
33
"introduction",
44
"installation",
5-
"migrate-from-reason-react"
5+
"migrate-from-v3"
66
],
77
"Main Concepts": [
88
"elements-and-jsx",
@@ -25,6 +25,7 @@
2525
],
2626
"Guides": [
2727
"beyond-jsx",
28-
"forwarding-refs"
28+
"forwarding-refs",
29+
"extensions-of-props"
2930
]
30-
}
31+
}

data/sidebar_react_v0100.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"Overview": [
3+
"introduction",
4+
"installation",
5+
"migrate-from-reason-react"
6+
],
7+
"Main Concepts": [
8+
"elements-and-jsx",
9+
"rendering-elements",
10+
"components-and-props",
11+
"arrays-and-keys",
12+
"refs-and-the-dom",
13+
"context",
14+
"styling",
15+
"router"
16+
],
17+
"Hooks & State Management": [
18+
"hooks-overview",
19+
"hooks-effect",
20+
"hooks-state",
21+
"hooks-reducer",
22+
"hooks-context",
23+
"hooks-ref",
24+
"hooks-custom"
25+
],
26+
"Guides": [
27+
"beyond-jsx",
28+
"forwarding-refs"
29+
]
30+
}

pages/docs/react/latest/beyond-jsx.mdx

+60-58
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ JSX is a syntax sugar that allows us to use React components in an HTML like man
1212

1313
</Intro>
1414

15-
**Note:** This section requires knowledge about the low level apis for [creating elements](./elements-and-jsx#creating-elements-from-component-functions), such as `React.createElement` or `ReactDOMRe.createDOMElementVariadic`.
15+
**Note:** This section requires knowledge about the low level apis for [creating elements](./elements-and-jsx#creating-elements-from-component-functions), such as `React.createElement` or `ReactDOM.createDOMElementVariadic`.
1616

17-
> **Note:** This page assumes your `bsconfig.json` to be set to `"reason": { "react-jsx": 3 }` to apply the right JSX transformations.
17+
> **Note:** This page assumes your `bsconfig.json` to be set to `"jsx": { "version": 4 }` to apply the right JSX transformations.
1818
1919
## Component Types
2020

@@ -24,22 +24,19 @@ Here are some examples on how to define your own component types (often useful w
2424

2525
```res
2626
// Plain function type
27-
type friendComp =
28-
({"name": string, "online": bool}) => React.element;
27+
type friend = {name: string, online: bool}
28+
type friendComp = friend => React.element
2929
3030
// Equivalent to
31-
// ({"padding": string, "children": React.element}) => React.element
32-
type containerComp =
33-
React.component<{
34-
"padding": string,
35-
"children": React.element
36-
}>;
31+
// ({padding: string, children: React.element}) => React.element
32+
type props = {padding: string, children: React.element}
33+
type containerComp = React.component<props>
3734
```
3835
The types above are pretty low level (basically the JS representation of a React component), but since ReScript React has its own ways of defining React components in a more language specific way, let's have a closer look on the anatomy of such a construct.
3936

4037
## JSX Component Interface
4138

42-
A ReScript React component needs to be a (sub-)module with a `make` and `makeProps` function to be usable in JSX. To make things easier, we provide a `@react.component` decorator to create those functions for you:
39+
A ReScript React component needs to be a (sub-)module with a `make` function and `props` type to be usable in JSX. To make things easier, we provide a `@react.component` decorator to create those functions for you:
4340

4441
<CodeTab labels={["Decorated", "Expanded"]}>
4542

@@ -56,15 +53,13 @@ module Friend = {
5653
```
5754
```res
5855
module Friend = {
59-
@obj
60-
external makeProps: (
61-
~name: string,
62-
~children: 'children,
63-
~key: string=?,
64-
unit) => {"name": string, "children": 'children} = "";
65-
66-
let make = (props: {"name": string, "children": 'children}) => {
67-
// React element creation from the original make function
56+
type props<'name, 'children> = {
57+
name: 'name,
58+
children: 'children,
59+
}
60+
61+
let make = ({name, children, _}: props<string, 'children>) => {
62+
ReactDOM.createDOMElementVariadic("div", [{React.string(name)}, children])
6863
}
6964
}
7065
```
@@ -73,11 +68,9 @@ module Friend = {
7368

7469
In the expanded output:
7570

76-
- `makeProps`: A function that receives multiple labeled arguments (according to prop names) and returns the value that is consumed by make(props)
71+
- `props`: A generated record type that has fields according to the labeled arguments of the `make` function
7772
- `make`: A converted `make` function that complies to the component interface `(props) => React.element`
7873

79-
**Note:** The `makeProps` function will also always contain a `~key` prop.
80-
8174
### Special Case React.forwardRef
8275

8376
The `@react.component` decorator also works for `React.forwardRef` calls:
@@ -88,64 +81,58 @@ The `@react.component` decorator also works for `React.forwardRef` calls:
8881
```res
8982
module FancyInput = {
9083
@react.component
91-
let make = React.forwardRef((~className=?, ~children, ref_) =>
84+
let make = React.forwardRef((~className=?, ~children, ref) =>
9285
<div>
93-
// use ref_ here
86+
// use ref here
9487
</div>
9588
)
9689
}
9790
```
9891

9992
```res
10093
// Simplified Output
101-
module FancyInput = {
102-
@obj
103-
external makeProps: (
104-
~className: 'className=?,
105-
~children: 'children,
106-
~key: string=?,
107-
~ref: 'ref=?,
108-
unit,
109-
) => {"className": option<'className>, "children": 'children} = ""
110-
111-
let make =
112-
(~className=?, ~children) => ref_ => ReactDOMRe.createDOMElementVariadic("div", [])
113-
114-
let make = React.forwardRef(
115-
(props: {"className": option<'className>, "children": 'children}, ref_,) => {
116-
make(
117-
~className=props["className"],
118-
~children=props["children"],
119-
ref_)
120-
})
94+
type props<'className, 'children, 'ref> = {
95+
className?: 'className,
96+
children: 'children,
97+
ref?: 'ref,
12198
}
99+
100+
let make = (
101+
{?className, children, _}: props<'className, 'children, ReactRef.currentDomRef>,
102+
ref: Js.Nullable.t<ReactRef.currentDomRef>,
103+
) =>
104+
make(~className, ~children, ~ref, ())
122105
```
123106

124107
</CodeTab>
125108

126-
As shown in the expanded output above, our decorator desugars the function passed to `React.forwardRef` in the same manner as a typical component `make` function. It also creates a `makeProps` function with a `ref` prop, so we can use it in our JSX call (`<FancyInput ref=.../>`).
109+
As shown in the expanded output above, our decorator desugars the function passed to `React.forwardRef` in the same manner as a typical component `make` function. It also creates a `props` type with an optional `ref` field, so we can use it in our JSX call (`<FancyInput ref=.../>`).
127110

128111
So now that we know how the ReScript React component transformation works, let's have a look on how ReScript transforms our JSX constructs.
129112

130113
## JSX Under the Hood
131114

132115
Whenever we are using JSX with a custom component ("capitalized JSX"), we are actually using `React.createElement` to create a new element. Here is an example of a React component without children:
133116

134-
<CodeTab labels={["JSX", "Without JSX"]}>
117+
<CodeTab labels={["JSX", "Without JSX", "JS Output"]}>
135118

136119
```res
137-
<Friend name="Fred" age=1 />
120+
<Friend name="Fred" age=20 />
138121
```
139122
```res
140-
React.createElement(Friend.make, Friend.makeProps(~name="Fred", ~age=1, ()))
123+
// classic
124+
React.createElement(Friend.make, {name: "Fred", age:20})
125+
126+
// automatic
127+
React.jsx(Friend.make, {name: "Fred", age: 20})
141128
```
142129
```js
143130
React.createElement(Playground$Friend, { name: "Fred", age: 20 });
144131
```
145132

146133
</CodeTab>
147134

148-
As you can see, it uses `Friend.make` and `Friend.makeProps` to call the `React.createElement` API. In case you are providing children, it will use `React.createElementVariadic` instead (which is just a different binding for `React.createElement`):
135+
As you can see, it uses `Friend.make` to call the `React.createElement` API. In case you are providing children, it will use `React.createElementVariadic` instead (which is just a different binding for `React.createElement`):
149136

150137
<CodeTab labels={["JSX", "Without JSX", "JS Output"]}>
151138

@@ -157,11 +144,18 @@ As you can see, it uses `Friend.make` and `Friend.makeProps` to call the `React.
157144
```
158145

159146
```res
147+
// classic
160148
React.createElementVariadic(
161149
Container.make,
162-
Container.makeProps(~width=200, ~children=React.null, ()),
150+
{width: 200, children: React.null},
163151
[{React.string("Hello")}, {React.string("World")}],
164152
)
153+
154+
// automatic
155+
React.jsxs(
156+
Container.make,
157+
{width: 200, children: React.array([{React.string("Hello")}, {React.string("World")}])},
158+
)
165159
```
166160

167161
```js
@@ -170,12 +164,12 @@ React.createElement(Container, { width: 200, children: null }, "Hello", "World")
170164

171165
</CodeTab>
172166

173-
Note that the `~children=React.null` prop has no relevance since React will only care about the children array passed as a third argument.
167+
Note that the `children: React.null` field has no relevance since React will only care about the children array passed as a third argument.
174168

175169

176170
### Dom Elements
177171

178-
"Uncapitalized JSX" expressions are treated as DOM elements and will be converted to `ReactDOMRe.createDOMElementVariadic` calls:
172+
"Uncapitalized JSX" expressions are treated as DOM elements and will be converted to `ReactDOM.createDOMElementVariadic` calls:
179173

180174
<CodeTab labels={["JSX", "Without JSX", "JS Output"]}>
181175

@@ -184,11 +178,15 @@ Note that the `~children=React.null` prop has no relevance since React will only
184178
```
185179

186180
```res
187-
ReactDOMRe.createDOMElementVariadic("div", ~props=ReactDOMRe.domProps(~title="test", ()), [])
181+
// classic
182+
ReactDOM.createDOMElementVariadic("div", ~props={title: "test"}, [])
183+
184+
// automatic
185+
ReactDOM.jsx("div", {title: "test"})
188186
```
189187

190188
```js
191-
React.createElement("div", { title: "test" });
189+
React.createElement("div", { title: "test" });
192190
```
193191

194192
</CodeTab>
@@ -204,11 +202,15 @@ The same goes for uncapitalized JSX with children:
204202
```
205203

206204
```res
207-
ReactDOMRe.createDOMElementVariadic(
205+
// classic
206+
ReactDOM.createDOMElementVariadic(
208207
"div",
209-
~props=ReactDOMRe.domProps(~title="test", ()),
210-
[ReactDOMRe.createDOMElementVariadic("span", [])],
208+
~props={title: "test"},
209+
[ReactDOM.createDOMElementVariadic("span", [])],
211210
)
211+
212+
// automatic
213+
ReactDOM.jsx("div", {title: "test", children: ?ReactDOM.someElement(ReactDOM.jsx("span", {}))})
212214
```
213215

214216
```js

0 commit comments

Comments
 (0)