-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Add events
plugin to @ngrx/signals
#4580
Comments
Well, I don't see ANY reason why this shouldn't land. 💯👍 |
Very nice! 👏🏿 I wonder: any specific reason why there isn't a |
Hurray! 🚀 Redux-like state handling is the missing part - at least for us and our project 💯 |
Is it something like global actions? I mean, actions that any store can intercept. |
Great work @markostanimirovic as @rainerhahnekamp stated just ship it 😉👍 |
@markostanimirovic looks fantastic |
Damn it, so I'll be the one "against" 😉 The main selling point behind NGRX-SS for me is its simplicity. The core (withState, withComputed, withMethods) is basically getting native angular stuff - but organizing it and making composable. Simple + composable + thin layer over native APIs -> win. Nobody enforces to use a "plugin". But if majority of the community walked in redux style direction, I'd see it as a step backwards in terms of simplicity. Redux style includes significant tradeoffs and it does make sense to be used - but not in all scenarios. From my personal experience, I've seen redux far many more times abused than used properly. Hope that doesn't happen to NGRX signal store. |
Looks great! What about returning multiple events in an effect, similar to using |
Great work as always, @markostanimirovic. This is exactly what we need and turns the Signal Store into a perfect state management solution, where devs may start lean and add the event-based API if needed later.
Defining Events as with-Feature inside a Signal Store definition would not be a good idea as it leads to coupling of a single Signal Store instance to dispatch Events, which need to have a global nature in Redux-like patterns.
Self-dispatching means, that you do not need to call dispatch to pass in an Event, but just execute a method, pass in a payload if needed and the dispatching works automatically behind the covers.
Yes, exactly that. |
@rainerhahnekamp and @markostanimirovic so so goooood🔥❤️ Having back a global event bus is so important🛠️ New people will use anyway signals in angular cause of angular docs and so will choose first the non redux way. so no worries about going in the wrong direction as those with redux needs would stay at ngrx store. this plugin just helps going in the right direction! |
I think it's also a nice idea, if someone wants to inject a store that has both dispatch and get-data functionality, then its possible to define: export const injectUserStore = () => ({ ...inject(UserStore), ...injectDispatch(userEvents) }); Maybe it would be nice to include some store-feature that merges action dispatcher into store or util / docs about it e.g. export const injectStoreWithDispatch = <
T extends Type<StateSource<any>>,
EventGroup extends Record<string, EventCreator | EventWithPropsCreator>,
>(
store: T,
events: EventGroup
): Prettify<InjectDispatchResult<EventGroup> & InstanceType<T>> => ({
...inject<InstanceType<T>>(store),
...injectDispatch(events),
}); |
Just discovered this feature at ng poland conf. This seems to be a game changer for our team for migration from global store to signal store. Waiting to be landed 🔥 |
Hi @markostanimirovic I think we should already consider a possibility to connect redux dev-tools. I have a working hacky solution here, that could be used as an inspiration, but with the ability to change @ngrx internal packages, it would be possible to easily create a fully functional and quality solution. |
I like that events can be created outside of the store 🤩 |
this is (when i understand you @CrazyJoker correctly) - see here https://ngrx.io/guide/eslint-plugin/rules/no-multiple-actions-in-effects - not recommended. |
could |
I have mixed feelings about this. This is a great implementation of a redux approach to signal store, but I agree with @ducin, this takes away from the simplicity of what signal-store gives us. Signals in general is a big step towards simplicity (computed is easier than dealing with rxjs pipes), and signal-store is already a great tool for organizing state with signals. With the reactivity we get from signals, I guess the question is, do we really need these events? |
💯. Or, slightly rephrased: Do we need to put redux-alike impl. everywhere? (given that it is already implemented in so many places) |
Events are really needed sometimes, but they have a cost. Similar to
This is a list of reasons why I believe events should be avoided when possible and direct calls should be preferred. |
I would definitely need it but I would never dispatch anything from the outside but instead, from within a feature that would trigger an effect on the parent like:
Would that be a valid use case or am I missing something (pretty new to stores tbh)? I tried with an effect in the onInit hook but it went into an infinite loop even though the only dependency there was the selectedCategory EDIT: I could actually use the dispatcher outside of a store/feature in very specific/rare cases but would clearly avoid it as much as possible |
@LcsGa , The same applies to pagination. Then, in the component that displays the items, I would use inputs bound to query params, so they would change on navigation and load items using those params. But I might have misunderstood your case. |
Yep, that could be a way of handling this but it doesn't fit my use case:
|
@LcsGa component with the grid will not be destroyed/reloaded if you navigate to the same route. There are other ways, of course:
|
Yes I completely agree with you but unfortunately I can't do that due to my pagination, as it's made rn. If I had a paginator, I'd do that right away (even though in my case + the router solution, I could simply use an |
🤯 this would make the SignalStore the most versatile state management ever. I would emphasize that:
what a team! 💪 |
Really awesome and simple implementation. I would definitely like to give it a try. I like the last bit about scaling up where everything is so neat and concise. |
Which @ngrx/* package(s) are relevant/related to the feature request?
signals
Information
This RFC proposes adding the
events
plugin to the@ngrx/signals
package to enable event-based state management with NgRx SignalStore.Key Principles
Prototype
The prototype of the
@ngrx/signals/events
plugin with a demo application is available at the following link: https://github.com/markostanimirovic/ngrx-signals-events-prototypeWalkthrough
Defining Events
Event creators are defined using the
eventGroup
function:Performing State Changes
The reducer is added to the SignalStore using the
withReducer
feature. Case reducers are defined using thewhen
function:Performing Side Effects
Side effects are added to the SignalStore using the
withEffects
feature:Dispatched events can be listened to using the
Events
service.If an effect returns a new event, it will be dispatched automatically.
Reading State
State and computed signals are accessed via store instance:
Dispatching Events
Events are dispatched using the
Dispatcher
service:It's also possible to define self-dispatching events using the
injectDispatch
function:Scaling Up
The reducer can be moved to a separate file using the custom SignalStore feature:
The same can be done for effects:
The final SignalStore implementation will look like this:
Describe any alternatives/workarounds you're currently using
No response
I would be willing to submit a PR to fix this issue
The text was updated successfully, but these errors were encountered: