Skip to content

Commit b538e55

Browse files
committed
Improve arrays-and-keys, components-and-props, introduction and rendering-elements
1 parent 98e02e9 commit b538e55

File tree

4 files changed

+29
-16
lines changed

4 files changed

+29
-16
lines changed

pages/docs/react/latest/arrays-and-keys.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Whenever we are transforming data into an array of elements and put it in our Re
1515

1616
## Keys & Rendering Arrays
1717

18-
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
18+
Keys help React identify which elements have been changed, added, or removed throughout each render. Keys should be given to elements inside the array to give the elements a stable identity:
1919

2020
```res
2121
let numbers = [1, 2, 3, 4, 5];
@@ -40,7 +40,7 @@ let items = Belt.Array.map(todos, todo => {
4040
})
4141
```
4242

43-
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
43+
If you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
4444

4545
```res {2,3}
4646
let items = Belt.Array.mapWithIndex(todos, (todo, i) => {
@@ -119,5 +119,7 @@ let items =
119119
<div> {React.array(items)} </div>
120120
```
121121

122-
We used `Belt.List.toArray` to convert our list to an array before creating our `array<React.element>`. Please note that using `list` has a performance impact due to extra conversion costs.
122+
We use `Belt.List.toArray` to convert our list to an array before creating our `array<React.element>`. Please note that using `list` has performance impact due to extra conversion costs.
123+
124+
In 99% you'll want to use arrays (seamless interop, faster JS code), but in some cases it might make sense to use a `list` to leverage advanced pattern matching features etc.
123125

pages/docs/react/latest/components-and-props.mdx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,13 @@ var greeting = React.createElement(Playground$Greeting, tmp);
143143

144144
</CodeTab>
145145

146-
### Children Props
146+
### Special Props `key` and `ref`
147+
148+
You can't define any props called `key` or `ref`. React treats those props differently and the compiler will will yield an error whenever you try to define a `~key` or `~ref` argument in your component function.
149+
150+
Check out the corresponding [Arrays and Keys](./arrays-and-keys) and [Forwarding React Refs](./forwarding-refs) sections for more details.
151+
152+
## Children Props
147153

148154
In React `props.children` is a special attribute to represent the nested elements within a parent element:
149155

@@ -250,17 +256,18 @@ module NoChildren = {
250256
<NoChildren> <div/> </NoChildren>
251257
```
252258

253-
Children props are really tempting to be abused as a way to model hierarchies, e.g. `<List> <ListHeader/> <Item/> </List>` (`List` should only allow `Item` / `ListHeader` elements), but this kind of constraint is hard to enforce because all components end up being `React.element`, so it would require notorious runtime checking within `List` to verify that all children are in fact of type `Item` or `ListHeader`.
259+
Children props are really tempting to be abused as a way to model hierarchies, e.g. `<List> <ListHeader/> <Item/> </List>` (`List` should only allow `Item` / `ListHeader` elements), but this kind of constraint is hard to enforce because all components end up being a `React.element`, so it would require notorious runtime checking within `List` to verify that all children are in fact of type `Item` or `ListHeader`.
254260

255-
The best way to approach this kind of issue is by using props instead of children, e.g. `<List header="..." items=[{id: "...", text: "..."}]/>`. This way it's easy to type check the constraints, and also spares us many hours debugging and remembering component constraints.
261+
The best way to approach this kind of issue is by using props instead of children, e.g. `<List header="..." items=[{id: "...", text: "..."}]/>`. This way it's easy to type check the constraints, and it also spares component consumers from memorizing and remembering component constraints.
256262

257-
**The best use-case for `children` is to pass down `React.element`s, no matter what kind of elements they are!**
263+
**The best use-case for `children` is to pass down `React.element`s without any semantic order or implementation details!**
258264

259265

266+
## Props & Type Inference
260267

261-
### Type Inference
268+
The ReScript type system is really good at inferring the prop types just by looking at its prop usage.
262269

263-
The ReScript type system excels at computing the actual prop types through usage. We recommend to explicitly type your props (especially for exported components) to help your coworkers understand the types. For simple cases or experimentation, it's still fine to omit them:
270+
For simple cases, well-scoped usage, or experimentation, it's still fine to omit type annotations:
264271

265272

266273
```res
@@ -275,8 +282,9 @@ let make = (~onClick, ~msg, ~children) => {
275282
}
276283
```
277284

278-
In the example above, `onClick` will be inferred as `ReactEvent.Mouse.t => unit`, `msg` as `string` and `children` as `React.element`. Type inference is very useful to ommit a lot of annoying type annotations, especially for private functions that pass around values to other functions.
285+
In the example above, `onClick` will be inferred as `ReactEvent.Mouse.t => unit`, `msg` as `string` and `children` as `React.element`. Type inference is especially useful when you just forward values to some smaller (privately scoped) functions.
279286

287+
Even tough type inference spares us a lot of keyboard typing, we still recommend to explicitly type your props (just like with any public API) for better type visibility and to prevent confusing type errors.
280288

281289
## Using Components in JSX
282290

@@ -309,6 +317,8 @@ var make = App;
309317

310318
**Note:** React components are capitalized; primitive DOM elements like `div` or `button` are uncapitalized. More infos on the JSX specifics and code transformations can be found in our [JSX section](/docs/manual/latest/jsx#capitalized-tag) in our language manual.
311319

320+
More details on the `@react.component` decorator and its generated interface can be found in our [Advanced React JSX Transformation](./react-jsx-transformation) page.
321+
312322

313323
## Submodule Components
314324

pages/docs/react/latest/introduction.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ ReScript offers first class bindings for [ReactJS](https://reactjs.org) and are
1111

1212
The ReScript philosophy is to compile as closely to idiomatic JS code as possible; in case of ReactJS we made no exception, so it's not only easy to transfer all the React knowledge to the ReScript platform, but also straightorward to integrate with existing ReactJS codebases and libraries.
1313

14+
All our documentated examples can be compiled in our [ReScript Playground](/try) as well.
15+
1416
> **This documentation assumes basic knowledge about ReactJS.**
1517
>
1618
> Please note that even though we will cover many basic React concepts, it might still be necessary to have a look at the official [ReactJS](https://reactjs.org) resources, especially if you are a complete beginner with React.

pages/docs/react/latest/rendering-elements.mdx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,28 @@ React.createElement("div", undefined, element);
123123

124124
</CodeTab>
125125

126-
127-
### Clone Elements
126+
## Cloning Elements
128127

129128
**Note:** This is an escape hatch feature and will only be useful for interoping with existing JS code / libraries.
130129

131-
Sometimes it's required to clone an existing element to set overwrite prop values or add props to a new instance. You can use `React.cloneElement` for that:
130+
Sometimes it's required to clone an existing element to set, overwrite or add prop values to a new instance, or if you want to set invalid prop names such as `data-name`. You can use `React.cloneElement` for that:
132131

133132
<CodeTab labels={["ReScript", "JS Output"]}>
134133

135134
```res
136135
let original = <div className="hello"/>
137136
138137
// Will return a new React.element with className set to "world"
139-
React.cloneElement(original, {"className": "world"});
138+
React.cloneElement(original, {"className": "world", "data-name": "some name"});
140139
```
141140
```js
142141
var original = React.createElement("div", {
143142
className: "hello"
144143
});
145144

146145
React.cloneElement(original, {
147-
className: "world"
146+
className: "world",
147+
"data-name": "some name"
148148
});
149149
```
150150

@@ -154,7 +154,6 @@ The feature mentioned above could also replicate `props spreading`, a practise c
154154

155155
In ReScript, we rather pass down required props explicitly to leaf components or use a renderProp instead. We introduced [JSX punning](/docs/manual/latest/jsx#punning) syntax to make the process of passing down props more convenient.
156156

157-
158157
## Using Elements within JSX
159158

160159
You can compose elements into more complex structures by using JSX:

0 commit comments

Comments
 (0)