Closed bytenik closed 4 years ago
Hi bytenik!
Yes, I am definitely open to hooks, and inside the react-bridge there is already a useStore()
hook to obtain a copy of the store. But you are probably looking for a useState()
hook that returns the state right away? I'd of course like that too so yes please send a PR 👍
Out of my head I'd guess the signature would look something like:
function useState<TState = object, TSlice = TState>(projection?: (state: TState) => TSlice) { /* ... */ }
// possible usages:
// will not be very typesafe, and re-render on *every* action :(
const state = useState()
// better typing, still slow due to rerender on every action
const state = useState<MyStateType>()
// should auto-infer the type of the returned value to number
// providing a projection function will only trigger re-render if the shallow-equality test failed (=there is a real change)
const slice = useState<MyStateType>(state => state.counter)
What do you think?
That's exactly what I was thinking. Probably need to leave room for action maps too, similar to how the existing connect
function works.
Actually, I started working on it and the action map functionality felt very out of place. It was one thing when it was being used as a prop, but, in the hooks-based pattern it felt odd to take a reference to a subject but then to basically wave hands and pretend it was a function.
If someone really wants to do that, they could easily have a separate non-hook like subjectAsFunction<T>(subject: Subject<T>): (value: T) => void
to make that happen for them, which would be a one-liner wrapper around .next
.
By the way it occurs to me after I made it that useState
may be occupied by React. 😁 🙃
I'm going with useStoreState
.
Unfortunately, due to https://github.com/microsoft/TypeScript/issues/26242 still being open and not implemented, your third proposed use case with type inference for the state slice is not possible. The only way to get that level of inference is through a fluent-ish interface, which I implemented as well even though it feels a bit kludgy:
const slice = useSlicer<TestState>()(({message}) => ({ message }));
Thank you for merging the PR. Can you push out a new version to npm? Thanks!
This is now published in v3.6.0, thanks for your help 👍
Are you open to hooks-based access to state if I code it and submit a PR?
Something similar to how react-router has
withRouter
akin toconnect
, but also now hasuseRouteMatch
/useHistory
/ etc. etc.