usehooks
usehooks copied to clipboard
useBuildReducer (typescript-typesafe useReducer)
Maybe you're at the point where you accept Typescript-contributions - this can of course be used without typescript, but it really shines with typescript ;)
I've got a prototype of this scetched out here: https://codesandbox.io/s/kx4ml7521o
Essentially, you use it like this:
const [state, dispatchWithType] = useBuildReducer(
/* initial state: */ { data: "initial text" }
)
// add case/action type with payload definition
.withCase<"concat", string>("concat", (state, action) => ({
data: state.data + action.payload
}))
// add case/action type without payload
.withCase("toUpper", state => ({ data: state.data.toUpperCase() }))
// add case/action type without payload
.withCase("clear", () => ({ data: "" }))
.build();
and then you can use it like this:
dispatchWithType(type, payload);
so in this case:
dispatchWithType("concat", "some string");
// or
dispatchWithType("clear");
The nice thing about this is that typescript restricts action types to valid action types - and enforces correct payload types - so it's a typesafe useReducer.
I'm thinking about wrapping the reducers in immer
, like redux-starter-kit
does, but for now this is only a prototype - I'd like some opinion about this.
Here's a similar idea with another api - very close to the createSlice api of redux-starter-kit : https://codesandbox.io/s/vyv0zlr78y
I named it useLocalSlice
after createSlice
.
This one works like this:
const [state, dispatchAction] = useLocalSlice({
initialState: { data: "initial text" },
reducers: {
concat: (state, action: { payload: string }) => ({
data: state.data + action.payload
}),
toUpper: state => ({
data: state.data.toUpperCase()
}),
clear: () => ({ data: "" })
}
});
dispatching of actions is just done via
dispatchAction.concat("concatenate me!");
// or
dispatchAction.clear();
again, this is typesafe - you can only use existing action types, and only correct payload types
And a day later, the second implemention has immer integration, a test suite and is on npm ;) https://www.npmjs.com/package/use-local-slice
I would be honored if you would choose to promote this ^^