Skip to content

Instantly share code, notes, and snippets.

@vbfox
Last active October 4, 2017 09:10
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 vbfox/ccfd302323b764fb3329a550706e9bd6 to your computer and use it in GitHub Desktop.
Save vbfox/ccfd302323b764fb3329a550706e9bd6 to your computer and use it in GitHub Desktop.
Redux with discriminated unions
import { List } from "immutable";
import * as React from "react";
import { connect } from "react-redux";
import { Action, Dispatch } from "redux";
export enum ActionKind {
AddTodo = "ADD_TODO",
RemoveTodo = "REMOVE_TODO"
}
export interface SimpleAction<TType, TValue> extends Action {
readonly type: TType;
readonly value: TValue;
}
export const addTodo = (message: string) => ({ type: ActionKind.AddTodo, value: message });
export const removeTodo = (index: number) => ({ type: ActionKind.RemoveTodo, value: index });
export type TodoAction = SimpleAction<ActionKind.AddTodo, string> | SimpleAction<ActionKind.RemoveTodo, number>;
export function reduce(state: List<string> = List(), action: TodoAction) {
switch (action.type) {
case ActionKind.AddTodo: return state.push(action.value);
case ActionKind.RemoveTodo: return state.remove(action.value);
default: return state;
}
}
interface PropsFromDispatch {
addTodo(message: string): void;
removeTodo(index: number): void;
}
interface PropsFromState {
todos: List<string>;
}
function mapStateToProps(state: List<string>): PropsFromState {
return { todos: state };
}
function mapDispatchToProps(dispatch: Dispatch<List<string>>): PropsFromDispatch {
return {
addTodo: (message: string) => dispatch(addTodo(message)),
removeTodo: (index: number) => dispatch(removeTodo(index))
};
}
class MyConnectableComponent extends React.Component<PropsFromDispatch & PropsFromState> {
render() {
const todoItems = this.props.todos.map((t, i) => <li key={i}>{t}</li>);
return <ul>{todoItems}</ul>;
}
}
export const MyComponent = connect(mapStateToProps, mapDispatchToProps)(MyConnectableComponent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment