teasy-redux
v0.3.1
Published
Boilerplate free typings for redux
Downloads
5
Readme
TeaSy Redux
Utility functions for boilerplate free Redux with TypeScript
Installation
yarn add teasy-redux
or
npm i teasy-redux
Usage
Action Creators
const addTodo = createAction(
"ADD_TODO",
payload((text: string) => ({
id: Math.random(),
text,
})),
)
addTodo("text")
const actions = createActions({
addTodo: payload((text: string) => ({
id: Math.random(),
text,
})),
editTodo: payload<{ id: number; text: string }>(),
removeTodo: (id: number) => ({ payload: { id } }),
})
actions.addTodo("New text")
actions.editTodo({ id: 123, text: "Edited text" })
actions.removeTodo(123)
Reducers
type State = { id: number; text: string }[]
const reducer = createReducer<State, typeof actions>(
{
addTodo: (todos, { payload: { id, text } }) => {
return todos
},
editTodo: (todos, { payload: { id, text } }) => {
return todos
},
removeTodo: (todos, { payload: { id } }) => {
return todos
},
},
[],
)
const reducer = (todos: State, action: ActionUnion<typeof actions>): State => {
switch (action.type) {
case actions.addTodo.type: {
const { id, text } = action.payload
return todos
}
case actions.editTodo.type: {
const { id, text } = action.payload
return todos
}
case actions.removeTodo.type: {
const { id } = action.payload
return todos
}
default: {
return todos
}
}
}
Type Guards
if (is(anyAction, actions.addTodo)) {
// ...
}
if (is(anyAction, [actions.addTodo, actions.editTodo])) {
// ...
}
if (is(anyAction, actions)) {
// ...
}
Action Union
const actionsArr = [actions.addTodo, actions.removeTodo]
type Union1 = ActionUnion<typeof actions>
type Union2 = ActionUnion<typeof actionsArr>
Usage with useReducer Hook
const actions = createActions({
increment: payload<{ by: number }>(),
decrement: payload<{ by: number }>(),
})
const initialState = { count: 0 }
const reducer = createReducer<{ count: number }, typeof actions>(
{
increment: (state, { payload: { by } }) => {
return { count: state.count + by }
},
decrement: (state, { payload: { by } }) => {
return { count: state.count - by }
},
},
initialState,
)
export const Counter: FC = () => {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<div>
<button onClick={() => dispatch(actions.decrement({ by: 2 }))} />
<span>{state.count}</span>
<button onClick={() => dispatch(actions.increment({ by: 2 }))} />
</div>
)
}