Skip to content

Commit 1db7c85

Browse files
committed
fix review comments
1 parent b48ba8f commit 1db7c85

File tree

2 files changed

+25
-41
lines changed

2 files changed

+25
-41
lines changed

README.md

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -368,56 +368,33 @@ If you‘re having troubles understanding this example, I recommend the fantasti
368368

369369
_[Flow][] is a static type checker for JavaScript. This section is only relevant for you if you‘re using Flow in your application._
370370

371-
ReComponent comes with first class Flow support built in. By default, a ReComponent will behave like a regular Component and will require props and state to be typed:
371+
ReComponent comes with first class Flow support built in.
372+
When extending `ReComponent`, in addition to the `Props` and `State` types required by regular `React.Component`
373+
we need to specify the third generic parameter which should be a union of all actions used by the component.
374+
This ensures type-safety everywhere in the code of the component where the actions are used and
375+
even allows [exhaustiveness testing] to verify that every action is indeed handled.
372376

373377
```js
374378
import * as React from "react";
375379
import { ReComponent, Update } from "react-recomponent";
376380

377381
type Props = {};
378-
type State = { count: number };
382+
type State = { count: number, value: string };
383+
type Action = {| type: "CLICK" |} | {| type: "UPDATE_VALUE", payload: string |};
379384

380-
class UntypedActionTypes extends ReComponent<Props, State> {
381-
handleClick = this.createSender("CLICK");
382-
state = { count: 0 };
383-
384-
static reducer(action, state) {
385-
switch (action.type) {
386-
case "CLICK":
387-
return Update({ count: state.count + 1 });
388-
default:
389-
return NoUpdate();
390-
}
391-
}
392-
393-
render() {
394-
return (
395-
<button onClick={this.handleClick}>
396-
You’ve clicked this {this.state.count} times(s)
397-
</button>
398-
);
399-
}
400-
}
401-
```
385+
class TypedActions extends ReComponent<Props, State, Action> {
386+
// NOTE: we use `this.send` API because it ensures type-safety for action's `payload`
387+
handleClick = () => this.send({ type: "CLICK" });
388+
handleUpdateValue = (newValue: string) => this.send({ type: "UPDATE_VALUE", payload: newValue });
402389

403-
Without specifying our action types any further, we will allow all `string` values. It is, however, recommended that we type all action types using a union of string literals. This will further tighten the type checks and will even allow [exhaustiveness testing] to verify that every action is indeed handled.
404-
405-
```js
406-
import * as React from "react";
407-
import { ReComponent, Update } from "react-recomponent";
408-
409-
type Props = {};
410-
type State = { count: number };
411-
type ActionTypes = "CLICK";
412-
413-
class TypedActionTypes extends ReComponent<Props, State, ActionTypes> {
414-
handleClick = this.createSender("CLICK");
415390
state = { count: 0 };
416391

417392
static reducer(action, state) {
418393
switch (action.type) {
419394
case "CLICK":
420395
return Update({ count: state.count + 1 });
396+
case "UPDATE_VALUE":
397+
return Update({ value: action.payload });
421398
default: {
422399
return NoUpdate();
423400
}
@@ -426,9 +403,12 @@ class TypedActionTypes extends ReComponent<Props, State, ActionTypes> {
426403

427404
render() {
428405
return (
429-
<button onClick={this.handleClick}>
430-
You’ve clicked this {this.state.count} times(s)
431-
</button>
406+
<React.Fragment>
407+
<button onClick={this.handleClick}>
408+
You’ve clicked this {this.state.count} times(s)
409+
</button>
410+
<Input onValueChange={this.handleValueUpdate} />
411+
<React.Fragment/>
432412
);
433413
}
434414
}
@@ -438,7 +418,11 @@ Check out the [type definition tests](https://github.com/philipp-spiess/react-re
438418

439419
**Known Limitations With Flow:**
440420

441-
- While it is possible to exhaustively type check the reducer, Flow will still require every branch to return an effect. This is why the above examples returns `NoUpdate()` even though the branch can never be reached.
421+
- `this.send` API for sending actions is preferred over `this.createSender`. This is because `this.createSender`
422+
effectively types the payload as `any` (limitation we can't overcome for now), whereas `this.send` provides full type-safety
423+
for actions
424+
- While it is possible to exhaustively type check the reducer, Flow will still require every branch to return an effect.
425+
This is why the above examples returns `NoUpdate()` even though the branch can never be reached.
442426

443427
## API Reference
444428

__tests__/RePureComponent-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe("RePureComponent", () => {
2121
class Example extends RePureComponent {
2222
constructor() {
2323
super();
24-
this.handleClick = () => this.send({ type: "CLICK" });
24+
this.handleClick = this.createSender("CLICK");
2525
this.state = { count: 0 };
2626
}
2727

0 commit comments

Comments
 (0)