Replies: 2 comments
-
I made a demo to illustrate the erroneous states issue: https://codesandbox.io/s/falling-butterfly-rruwp?file=/src/App.tsx |
Beta Was this translation helpful? Give feedback.
0 replies
-
Started on this! #197 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi! 👋
At the moment, most hooks in the library return a structured object first, then one or multiple functions similar to this one:
https://github.com/tmm/wagmi/blob/0649fa5f0cafefd86f921ad81a5b0c2222a2ba67/packages/react/src/hooks/accounts/useBalance.ts#L53-L112
These functions do two different things:
I think this approach could be improved by moving the fetching part into a separate function, which could then either be exported by the library or kept private.
Proposal Summary
We would end up with two distinct functions:
accountBalance()
).refetch
function to the object like React Query does).The API of
accountBalance
would look like this:The refetch function would be straightforward in comparison:
Usage
Using the utility function could look like this:
Of course, using the hook would be the preferred way, this is how it would look:
The utility function could also be used in other contexts than React (e.g. Node, Vue, etc.):
Pros
It would bring the following advantages:
1. Prevent erroneous states
At the moment users can fetch data using the hook or a function returned by this hook, which seem side-effect free. It might seem convenient since users can temporarily override the config defined in the hook itself, except that the function will also override the state of the hook, even if their configs differ.
Edit: here is an illustration of the issue: https://codesandbox.io/s/falling-butterfly-rruwp?file=/src/App.tsx
2. Use promises to their full extent
React renders don’t know how to deal with thrown errors, so it currently always resolves, even in case of error:
https://github.com/tmm/wagmi/blob/0649fa5f0cafefd86f921ad81a5b0c2222a2ba67/packages/react/src/hooks/accounts/useBalance.ts#L105-L109
The problem of this approach is that it doesn’t allow to use the promise properly: try / catch wouldn’t work, neither would plugging it to other tools like React Query. Having a separate utility would allow to return the data directly, and to return errors by throwing them.
3. Provide one way to do things for users
These changes would encourage users to use the hook by providing the options and using the returned result. As pointed in the first point, using a different config for
getBalance()
is not recommended as it will result in the hook returning an erroneous state, so users should always be able to callrefetch()
and usedata
to get the value instead.4. Improve separation of concerns, provide more flexibility
The hook implementation would be more focused on the state itself, since the actual data fetching would be moved in
accountBalance()
. Managing async state in hooks can be tricky, and separating the data fetching implementation could help making it more clear.accountBalance()
would make be easier to maintain side-effect free once removed from the hook context, and if exported by the library, would provide flexible ways to use the library, at the cost of a more “advanced” API (since more parameters will be required to use these functions by providing them the context they need, like the provider).A lot of what would remain in
useBalance()
would be easy to move to a generic hook internally, which could end up in creating hooks simple hooks likeuseBalance()
in the following way:createWagmiHook()
would take care of everything else.5. Tests
Utility functions like
accountBalance()
would be easy to test, whilecreateWagmiHook()
tests could extensively focus on testing the way it manages state changes.Cons
Less flexibility when using the hook
It would remove the possibility to quickly use other parameters when using the hook. I would argue that using
getBalance()
with another config should be discouraged anyway, as it results in an erroneous state for the main hook. Using the utility function will be a possibility at the price of verbosity.Something that could mitigate this issue would be to allow multiple entries to be returned by the library hooks, when possible:
Breaking changes in the API
It’s always bad to break things, but I would consider the functions returned by the hooks as part of the “advanced API” anyway.
Related
Beta Was this translation helpful? Give feedback.
All reactions