Skip to content

Instantly share code, notes, and snippets.

@kakajika
Last active November 2, 2017 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kakajika/2e43244ff51fb3ec2c88ada0b3ed4041 to your computer and use it in GitHub Desktop.
Save kakajika/2e43244ff51fb3ec2c88ada0b3ed4041 to your computer and use it in GitHub Desktop.
Simple type-safe flux implementation with RxJS & TypeScript. Inspired by flumpt
import * as React from "react"
import * as Rx from "rxjs"
export class Action<T> {
constructor(public key: string) {}
}
interface FluxContext {
dispatch: <T extends any>(action: Action<T>, value: T) => void
}
export class Flux<State> extends React.Component<void, State> {
private subjects: { [key: string]: Rx.Subject<any> } = {}
on = <T extends any>(action: Action<T>, dispatcher: (value: T) => void) => {
const subject = new Rx.Subject<T>()
this.subjects[action.key] = subject
subject.subscribe(dispatcher)
}
static childContextTypes = {
dispatch: React.PropTypes.func
}
getChildContext(): FluxContext {
return {
dispatch: <T extends any>(action: Action<T>, value: T) => {
if (this.subjects[action.key]) {
this.subjects[action.key].next(value)
}
}
}
}
}
export class Component<Props, State> extends React.Component<Props, State> {
static contextTypes = {
dispatch: React.PropTypes.func
}
context: FluxContext
dispatch = this.context.dispatch
}
import {Flux, Action, Component} from ".flux"
const IncrementAction = new Action<void>("increment")
interface State {
count: number
}
class App extends Flux<State> {
state: State = {
count: 0
}
componentDidMount() {
this.on(IncrementAction, () => {
this.setState({ count: this.state.count + 1 })
})
}
render() {
return <MyComponent {...this.state}/>
}
}
class MyComponent extends Component<State, {}> {
render() {
return (
<div>
{this.props.count}
<button onClick={() => this.dispatch(IncrementAction)}>increment</button>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment