-
Notifications
You must be signed in to change notification settings - Fork 2
/
CounterList.tsx
39 lines (33 loc) · 1.38 KB
/
CounterList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { event, events, reduce, reduced } from "event-reduce";
import { reactive } from "event-reduce-react";
import * as React from "react";
import { Counter, CounterEvents, CounterModel } from "./Counter";
@events
export class CounterListEvents {
counterAdded = event();
counterRemoved = event<{ id: number }>();
incremented = event<{ id: number }>();
decremented = event<{ id: number }>();
reset = event<{ id: number }>();
}
let uid = 1;
export class CounterListModel {
constructor(public events: CounterListEvents) { }
@reduced
counters = reduce([] as CounterModel[], this.events)
.on(e => e.counterAdded, (cs) => cs.concat(this.createCounter({ id: uid++ })))
.on(e => e.counterRemoved, (cs, { id }) => cs.filter(c => c.id != id))
.onRestore((_, counterStates) => counterStates.map(c => this.createCounter(c)))
.value;
private createCounter(initial: { id: number, count?: number }) {
return new CounterModel(new CounterEvents(this.events, { id: initial.id }), initial);
}
}
export const CounterList = reactive(function CounterList({ model }: { model: CounterListModel; }) {
return <>
<div>
<button onClick={() => model.events.counterAdded()}>Add Counter</button>
</div>
{model.counters.map(c => <Counter key={c.id} model={c} />)}
</>
});