Skip to content

Commit d06bc25

Browse files
committed
Update React #next documentation
1 parent 7873c89 commit d06bc25

File tree

1 file changed

+130
-24
lines changed

1 file changed

+130
-24
lines changed

doc/react-next.md

+130-24
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,142 @@
11
# React #next
22

3-
Branch `#next` of my haxe-react fork aims to move haxe-react forward to 2.0.0+
4-
with an improved freedom to break things until I get them right.
3+
Branch `#next` of my haxe-react fork aims to move haxe-react forward to `2.0.0+`
4+
with an increased freedom to break things until I get them right.
55

66
This version of haxe-react can be considered unstable (even though it is
77
currently being used in production) due to these huge changes it can go through.
8+
You may want to lock your dependencies to the latest commit of the branch
9+
instead of the branch itself, if you are not willing to update your code every
10+
now and then. I am available in
11+
[haxe-react gitter](https://gitter.im/haxe-react/Lobby) if you need help.
812

913
## Different jsx parser
1014

1115
Based off [back2dos](https://github.com/back2dos)'s
12-
[PR #95](https://github.com/massiveinteractive/haxe-react/pull/95), tink_hxx is
13-
used to handle jsx.
16+
[PR #95](https://github.com/massiveinteractive/haxe-react/pull/95),
17+
[`tink_hxx`](https://github.com/haxetink/tink_hxx) is used to handle jsx.
1418

15-
This implies some little syntax changes:
19+
### Syntax changes
20+
21+
The change of parser implies some little syntax changes:
1622
* `prop=$42` and such are no longer allowed, use `prop=${42}` or `prop={42}`
1723
* `prop=${true}` can now be expressed as simply `prop`
1824

25+
### Misc changes
26+
1927
Other changes introduced by tink_hxx:
2028
* Props are type-checked against the component's `TProps`
2129
* You cannot pass props not recognized by the target component
30+
* [Needs a tink_hxx release] You can use `${/* comments */}` / `{/* comments */}`in jsx
31+
32+
### Further changes added in `#next`
33+
34+
#### [`6e8fe8d`](https://github.com/kLabz/haxe-react/commit/6e8fe8d) Allow String variables as jsx node
35+
36+
The new parser will resolve `String` variables for node names:
37+
38+
```haxe
39+
var Node = isTitle ? 'h2' : 'p';
40+
return jsx('<$Node>${props.children}</$Node>');
41+
```
42+
43+
**Warning**: it only works for variable names starting with an uppercase letter.
44+
45+
#### [`d173de0`](https://github.com/kLabz/haxe-react/commit/d173de0) Fix error position when using invalid nodes in jsx
46+
47+
Using an invalid node inside jsx, such as `<$UnknownComponent />`, resulted in
48+
an error inside `haxe.macro.MacroStringTools`.
49+
50+
This fix ensures that the position points to "UnknownComponent" inside the jsx
51+
string.
52+
53+
#### [`578c55d`](https://github.com/kLabz/haxe-react/commit/578c55d) Disallow invalid values inside jsx when a fragment is expected
54+
55+
For example, the following used to compile:
56+
57+
jsx('<div>${function() return 42}</div>');
58+
59+
But resulted in a runtime error:
60+
61+
Warning: Functions are not valid as a React child. This may happen if you
62+
return a Component instead of <Component /> from render. Or maybe you meant
63+
to call this function rather than return it.
64+
65+
Or, for objects: `jsx('<div>${{test: 42}}</div>');` resulted in:
66+
67+
Uncaught Error: Objects are not valid as a React child (found: object with
68+
keys {test}). If you meant to render a collection of children,
69+
use an array instead.
70+
71+
Now we get a compilation error (see below for `react.ReactFragment`):
72+
73+
src/Index.hx:31: characters 7-17 : { test : Int } should be react.ReactFragment
74+
src/Index.hx:31: characters 7-17 : For function argument 'children'
75+
76+
#### [`425cb6c`](https://github.com/kLabz/haxe-react/commit/425cb6c) Ensure individual prop typing, allowing abstract props to do their magic
2277

23-
Further changes added in `#next`:
24-
* [`6e8fe8d`](https://github.com/kLabz/haxe-react/commit/6e8fe8d) Allow String variables as jsx node
25-
* [`d173de0`](https://github.com/kLabz/haxe-react/commit/d173de0) Fix error position when using invalid nodes in jsx
26-
* [`578c55d`](https://github.com/kLabz/haxe-react/commit/578c55d) Disallow invalid values inside jsx when a fragment is expected
27-
* [`425cb6c`](https://github.com/kLabz/haxe-react/commit/425cb6c) Ensure individual prop typing, allowing abstract props to do their magic
28-
* [`150b76d`](https://github.com/kLabz/haxe-react/commit/150b76d) Jsx: display compilation warning on missing props
78+
Makes sure each prop resolves to its type, with a `(prop :TypeOfProp)`.
79+
80+
This will trigger abstracts `@:from` / `@:to` which may be needed in some cases
81+
to do their magic.
82+
83+
#### [`150b76d`](https://github.com/kLabz/haxe-react/commit/150b76d) + [`d2e8dd3`](https://github.com/kLabz/haxe-react/commit/d2e8dd3) Jsx: display compilation warning on missing props
84+
85+
Tries to extract the list of needed props and adds a compilation warning when
86+
some of them are not passed in a jsx "call".
87+
88+
**Limitations:**
89+
* If you use the spread operator on the props of a component, this test is not
90+
executed (it becomes hard and even sometimes impossible to know what props are
91+
passed through the spread).
2992

3093
## ReactComponentOf cleanup
3194

32-
Cherry-picked
95+
Cherry-picked and improved
3396
[PR #108](https://github.com/massiveinteractive/haxe-react/pull/108), which
34-
removed the legacy `TRefs` from `ReactComponent`, so now we have:
35-
* `ReactComponentOf<TProps, TState>`
97+
removed the legacy `TRefs` from `ReactComponent`.
98+
99+
#### So now we have
100+
* `ReactComponentOf<TProps, TState>` (or `ReactComponentOfPropsAndState<TProps, TState>`)
36101
* `ReactComponentOfProps<TProps>`
37102
* `ReactComponentOfState<TState>`
38-
* `ReactComponentOfNothing`, for when you cannot use a static component and are
39-
using neither props nor state
40-
* And still `ReactComponent` which has untyped props and state
103+
* And still `ReactComponent` which has untyped props and state (`Dynamic`)
104+
105+
#### Strict props & state access
41106

42107
This is actually a big change, since `ReactComponentOfProps` and
43108
`ReactComponentOfState` use `react.Empty` type as `TState` (resp. `TProps`).
44109

45110
`react.Empty` is an empty typedef, disabling state access/update on
46111
`ReactComponentOfProps`, and props access in `ReactComponentOfState`.
47112

48-
`ReactComponentOfPropsAndState` is still available with the compilation flag
49-
`-D react_deprecated_refs`. Other TRefs-related typedefs have been removed.
50-
51113
## `ReactFragment`
52114

53115
`ReactFragment` (in `react.ReactComponent` module) tries to be closer to react
54116
in describing a valid element. It replaces `ReactElement` in most API, allowing
55117
them to use other types allowed by react.
56118

57-
`ReactFragment` unifies with either:
119+
#### `ReactFragment` unifies with either
120+
58121
* `ReactElement`
59122
* `String`
60123
* `Float` (and `Int`)
61124
* `Bool`
62125
* `Array<ReactFragment>`
63126

127+
#### APIs now using ReactFragment
128+
129+
* `React.createElement()` returns a ReactFragment
130+
* `ReactChildren.map()` callback is now `ReactFragment -> ReactFragment`
131+
* `ReactChildren.foreach()` callback is now `ReactFragment -> Void`
132+
* `ReactComponent's render()` returns a ReactFragment
133+
* `ReactDOM.render()` uses ReactFragment for first argument and return type
134+
* `ReactDOM.hydrate()` uses ReactFragment for first argument and return type
135+
* `ReactDOM.createPortal()` uses ReactFragment for first argument and return type
136+
64137
## `ReactNode` and `ReactNodeOf`
65138

66-
`ReactNode` replaces `CreateElementType` and allows:
139+
`react.ReactNode` replaces `CreateElementType` and allows:
67140
* `String`
68141
* `Void->ReactFragment`
69142
* `TProps->ReactFragment`
@@ -73,7 +146,40 @@ them to use other types allowed by react.
73146
There is also `ReactNodeOf<TProps>`, for cases when you want a component
74147
accepting some specific props.
75148

149+
`CreateElementType`, still in the `react.React` module, is now **deprecated**
150+
but still available as a proxy to `ReactNode`.
151+
76152
## More debug tools
77153

78-
* [`98233c3`](https://github.com/kLabz/haxe-react/commit/98233c3) Add warning if ReactComponent's render has no override
79-
* [`ef0b0f1`](https://github.com/kLabz/haxe-react/commit/ef0b0f1) React runtime warnings: add check for state initialization
154+
#### [`98233c3`](https://github.com/kLabz/haxe-react/commit/98233c3) Add warning if ReactComponent's render has no override
155+
156+
Adds a compile-time check for an override of the `render` function in your
157+
components. This helps catching following runtime warning sooner:
158+
159+
Warning: Index(...): No `render` method found on the returned component
160+
instance: you may have forgotten to define `render`.
161+
162+
Catching it at compile-time also ensures it does not happen to a component only
163+
visible for a few specific application state.
164+
165+
You can disable this with the `-D react_ignore_empty_render` compilation flag.
166+
167+
#### [`ef0b0f1`](https://github.com/kLabz/haxe-react/commit/ef0b0f1) React runtime warnings: add check for state initialization
168+
169+
React runtime warnings, disabled by default, can be enabled with the
170+
`-D react_runtime_warnings` compilation flag (only when `-debug` is enabled).
171+
172+
They were previously enabled with `-D react_render_warning`, and only added the
173+
warning about avoidable re-renders. Note that this warning can have false
174+
positive due to the legacy context API (react-router for example). You can
175+
disable it for a specific component by adding `@:ignoreReRender` meta to this
176+
component ([`a7860c6`](https://github.com/kLabz/haxe-react/commit/a7860c6)).
177+
178+
A new warning has been added: if a component having a state does not have a
179+
constructor or has one but doesn't initialize its state in it, you will get a
180+
compilation error warning you about it (instead of a runtime react error).
181+
182+
These warnings are now more accurate since the strict props/state types have
183+
been added to `ReactComponentOf` typedefs. Compatibility has been handled
184+
mainly in [`1719431`](https://github.com/kLabz/haxe-react/commit/1719431) and
185+
[`241a13b`](https://github.com/kLabz/haxe-react/commit/241a13b).

0 commit comments

Comments
 (0)