Skip to content

Instantly share code, notes, and snippets.

@reidev275
Created July 15, 2019 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reidev275/4354bb64ba72dcd0c72068a2dc94bd7a to your computer and use it in GitHub Desktop.
Save reidev275/4354bb64ba72dcd0c72068a2dc94bd7a to your computer and use it in GitHub Desktop.
import * as React from "react";
import { Tea } from "./tea";
type Props = { start?: number };
type Message = "increment" | "decrement";
type Model = { count: number };
export class Counter extends Tea<Props, Message, Model> {
constructor(props: Props) {
super(props);
this.state = { count: props.start || 0 };
}
update(msg: Message, model: Model): Model {
switch (msg) {
case "increment":
return { count: model.count + 1 };
case "decrement":
return { count: model.count - 1 };
}
}
view(m: Model, emit: (message: Message) => any) {
return (
<div>
<button onclick={() => emit("decrement")}>-</button>
{m.count}
<button onclick={() => emit("increment")}>+</button>
</div>
)
}
}
import React from "react";
export abstract class Tea<P, U, M> extends React.Component<P, M> {
constructor(props: P) {
super(props);
this.dispatch = this.dispatch.bind(this);
this.view = this.view.bind(this);
}
abstract update(msg: U, model: M): M | [M, Promise<U>];
abstract view(model: M, emit: (message: U) => any): React.ReactNode;
render(): React.ReactNode {
return this.view(this.state, this.dispatch)
}
dispatch(msg: U) {
const x = this.update(msg, this.state)
if (x instanceof Array) {
const [m, p] = x
this.setState(m)
p.then(y => this.dispatch(y))
} else {
this.setState(x)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment