You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The other day I was using a slice pattern and wanted to subscribe to store changes inside one of the slices. I figured out that I had to add subscribeWithSelector() middleware to the entire store, and then used the api.subscribe() inside the slice. Here's an illustration:
Basically, the idea is to have 2nd slice have logic that reacts to changes in the store, using the passed-in subscribe function. If we didn't use subscribeWithSelector middleware, and subsequently used original api.subscribe() without a selector, it would work fine. But with subscribeWithSelector middleware, the above code throws an error.
Basically, the new .subscribe() attempt to run the selector (in our case, (s) => s.emitter) immediately during the call to subscribe. But inside the slice state creator the state hasn't been created yet! State is created AFTER the state creator returns. So obviously this throws an error about not being able to ready property emitter from undefined.
My point here is that maybe running the selector at the time of subscription is not entirely correct? You can argue it many ways, of course. But the fact that the original .subscribe() (without selector) works fine, i.e. just adds a listener, indicates that the "enhanced" .subscribe() should behave similarly? I am not sure about the philosophy of using .subscribe() inside a state creator, but it is being passed in, so I imagine it should be fair game, right?
The way I would fix, is probably by changing above line to:
One can also argue that I can solve this by a quick hack to my selector, e.g. (s) => s?.emitter, but it does feel like a hack. I feel like the expectation is that selector would be called when state exists. What do you think?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
The other day I was using a slice pattern and wanted to subscribe to store changes inside one of the slices. I figured out that I had to add
subscribeWithSelector()
middleware to the entire store, and then used theapi.subscribe()
inside the slice. Here's an illustration:Basically, the idea is to have 2nd slice have logic that reacts to changes in the store, using the passed-in subscribe function. If we didn't use
subscribeWithSelector
middleware, and subsequently used originalapi.subscribe()
without a selector, it would work fine. But withsubscribeWithSelector
middleware, the above code throws an error.It has to do with this:
zustand/src/middleware/subscribeWithSelector.ts
Line 55 in 7980a7b
Basically, the new
.subscribe()
attempt to run the selector (in our case,(s) => s.emitter
) immediately during the call to subscribe. But inside the slice state creator the state hasn't been created yet! State is created AFTER the state creator returns. So obviously this throws an error about not being able to ready propertyemitter
fromundefined
.My point here is that maybe running the selector at the time of subscription is not entirely correct? You can argue it many ways, of course. But the fact that the original
.subscribe()
(without selector) works fine, i.e. just adds a listener, indicates that the "enhanced".subscribe()
should behave similarly? I am not sure about the philosophy of using.subscribe()
inside a state creator, but it is being passed in, so I imagine it should be fair game, right?The way I would fix, is probably by changing above line to:
and then also:
One can also argue that I can solve this by a quick hack to my selector, e.g.
(s) => s?.emitter
, but it does feel like a hack. I feel like the expectation is that selector would be called when state exists. What do you think?Beta Was this translation helpful? Give feedback.
All reactions