Skip to content

Commit bf634dc

Browse files
committed
Add more reducers
1 parent e017a2d commit bf634dc

File tree

2 files changed

+96
-14
lines changed

2 files changed

+96
-14
lines changed

lib/components_guide_web/templates/react_typescript/logical-clocks.html.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ We can implement once as a React hook using `useReducer()`:
1616

1717
```ts
1818
function useTicker() {
19-
return useReducer(n => n + 1, 0);
19+
return useReducer(t => t + 1, 0);
2020
}
2121
```
2222

@@ -27,7 +27,7 @@ const [count, advance] = useTicker();
2727

2828
return <>
2929
<p>You have clicked {count} times</p>
30-
<button>Click me!</button>
30+
<button onClick={advance}>Click me!</button>
3131
</>;
3232
```
3333

lib/components_guide_web/templates/react_typescript/reducer-patterns.html.md

Lines changed: 94 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,33 @@
44

55
```js
66
const [isEnabled, enable] = useReducer(() => true, false);
7+
8+
isEnabled; // false
9+
enable();
10+
isEnabled; // true
11+
enable();
12+
isEnabled; // true
713
```
814

915
[Source](https://twitter.com/markdalgleish/status/1521304112738217984)
1016

1117
## Toggle Flag
1218

1319
```js
14-
const [on, toggle] = useReducer(flag => !flag, false)
20+
const [on, toggle] = useReducer(flag => !flag, false);
21+
22+
on; // false
23+
toggle();
24+
on; // true
25+
toggle();
26+
on; // false
27+
toggle();
28+
on; // true
1529
```
1630

1731
[Source](https://twitter.com/FernandoTheRojo/status/1521305729558274048)
1832

19-
## Menu
33+
## Menu or Exclusive Value
2034

2135
```ts
2236
type Menu = null | "file" | "edit" | "view"; // null means closed
@@ -32,16 +46,26 @@ const [openMenu, tap] = useReducer(
3246
null
3347
);
3448

35-
tap("file") // "file"
36-
tap(null) // null
37-
tap("file") // "file"
38-
tap("file") // null
39-
tap("file") // "file"
40-
tap("edit") // "edit"
41-
tap("view") // "view"
42-
tap("edit") // "edit"
43-
tap("edit") // null
44-
tap(null) // null
49+
tap("file");
50+
openMenu; // "file"
51+
tap(null);
52+
openMenu; // null
53+
tap("file");
54+
openMenu; // "file"
55+
tap("file");
56+
openMenu; // null
57+
tap("file");
58+
openMenu; // "file"
59+
tap("edit");
60+
openMenu; // "edit"
61+
tap("view");
62+
openMenu; // "view"
63+
tap("edit");
64+
openMenu; // "edit"
65+
tap("edit");
66+
openMenu; // null
67+
tap(null);
68+
openMenu; // null
4569
```
4670

4771
You can of course condense it to a ternary if you want:
@@ -53,3 +77,61 @@ const [openMenu, tap] = useReducer(
5377
null
5478
);
5579
```
80+
81+
## Logical Clock
82+
83+
```js
84+
const [t, tick] = useReducer(n => n + 1, 0);
85+
86+
t; // 0
87+
tick();
88+
t; // 1
89+
tick();
90+
t; // 2
91+
tick();
92+
t; // 3
93+
```
94+
95+
----
96+
97+
## Lamport Timestamp
98+
99+
```js
100+
const [{ t, toSend }, dispatch] = useReducer((state, command) => {
101+
if (command.type === "send") {
102+
const t = state.t + 1;
103+
return {
104+
t,
105+
toSend: {
106+
t,
107+
message: command.message
108+
}
109+
};
110+
} else if (command.type === "receive") {
111+
const t = Math.max(state.t, command.t) + 1;
112+
return {
113+
t,
114+
toSend: null
115+
};
116+
} else {
117+
return {
118+
t: state.t,
119+
toSend: null
120+
};
121+
}
122+
}, { t: 0, toSend: null });
123+
useEffect(() => {
124+
if (toSend !== null) {
125+
send(toSend.message, toSend.t); // Second argument can be used for idempotency
126+
}
127+
}, [toSend]);
128+
129+
t; // 0
130+
toSend; // null
131+
dispatch({ type: "send", message: "hello" });
132+
t; // 1
133+
toSend; // { t: 1, message: "hello" }
134+
dispatch({ type: "receive", t: 3, message: "howdy" });
135+
t; // 4
136+
toSend; // null
137+
```

0 commit comments

Comments
 (0)