cassiozen / useStateMachine

The <1 kb state machine hook for React
MIT License
2.38k stars 47 forks source link

Generic over states and transitions #11

Closed RunDevelopment closed 3 years ago

RunDevelopment commented 3 years ago

PR for my suggestion under your reddit post.

Type changes:

Behavioral changes:

Feel free to request changes.

You can try out everything here.

cassiozen commented 3 years ago

Wow, @RunDevelopment, this is spectacular; thanks so much for your time!

I don't know why you added them in the first place.

Because I lack knowledge. This is the first project where I use TypeScript beyond the basics...

The type parameter of useStateMachine is no longer constrained. From what I see, this only got in the way of TS inferring the type. I'll re-add it if it's important.

It makes sense now. I don't think we need to re-add.

Therefore currentState must be non-nullable

👍

Context will no longer default to {}

👍

I also noticed you changed the reducer to always accept a type in the action and expose send as a function that dispatches { type: "Transition" ... instead of exposing the useReducer dispatch directly. A clever solution, very obvious, I don't know why I didn't think of that from the beginning 😅.

One change I will do in this case is renaming the internal send to dispatch to be more idiomatic - but I can do that separately, you already contributed with a lot.

Overall, thanks again a lot for your PR - this is as much an improvement for the library as a learning opportunity for me. Please let me know if you think of any other suggestions in the future.

cassiozen commented 3 years ago

Oh, I remembered why I this all that trickery with the send method: I wanted to completely reuse dispatch because it's stable across re-renders. There is the possibility that some user will pass send to child components - if these components use PureComponent or React.memo, an unstable send method will make them useless.

Not a big issue, can be definitely dealt with on a separate occasion.

RunDevelopment commented 3 years ago

Ahh, that's true. The methods we give out might behave the same but they aren't the same object.

I wonder, is there an idiomatic way to do this in the React world or will it be a WeakMap solution?

cassiozen commented 3 years ago

Yes, I can use either useMemo or useCallback.

cassiozen commented 3 years ago

@all-contributors please add @RunDevelopment for code, test and ideas.

allcontributors[bot] commented 3 years ago

@cassiozen

I've put up a pull request to add @RunDevelopment! :tada: