RFC: Standalone NgRx APIs #3399
Replies: 7 comments 11 replies
-
About the functions - that's an amazing idea! My humble opinion: since they are supposed to be used inside the "providers", it would be logical and intuitive to call "provideStore", "provideEffects", "provideSomethingElse" - this way you obviously create a collection of providers. |
Beta Was this translation helpful? Give feedback.
-
What's the actual difference except for naming and static mark? |
Beta Was this translation helpful? Give feedback.
-
I'd rather use It's a good question to ask though whether we should just wrap existing APIs for now. For reference, we used to have |
Beta Was this translation helpful? Give feedback.
-
We recently had a discussion with @brandonroberts about where should we lift the state/effects initialization: bootstrap? router? somewhere else? Here are the tradeoffs: at BootstrapboostrapApplication(MyApp, {providers: [provideEffects(...)]}) This is a quite nice place and it’s clearly the highest common point… now, the problem is that it requires eager loading all states/effects (so no lazy loading) and this doesn’t scale as the main bundle will keep getting larger and larger. at Router levelRouter allows lazy loading but is it the highest common point after the bootstrap? Not really. In fact, a state will mostly be used by components under some shared route but quickly while the app grows, one might want to reuse the component under another route or anywhere else in the app and that’s when things get tricky. As we broke the locality principle, we have to think about checking out the route providers and move the state/effects to somewhere higher… which will end up being the bootstrap… and thus the clutter in the main bundle. TL;DRProviding state at bootstrap clutters the bundle and providing state at router level doesn’t scale either as one has to keep thinking about which state should be provided Concrete exampleAn app with an AlternativesComponents should be able to tell that they are part of a "feature" and that the feature's state/effects should be initialized when the first component of this feature is loaded. @Component({})
class RecipeSearchCmp {
store = injectRecipeStore();
}
function injectRecipeStore() {
const store = inject(Store);
store.addFeature(recipeReducers);
store.addEffects([...]);
return store;
} We can think of more composable functions of course (e.g. This also kind of breaks Ngrx indirection but it helps make sure that a feature's or a library's components will never be used without having the state/effects loaded. |
Beta Was this translation helpful? Give feedback.
-
Are there currently any generators for creating a standalone component with an ngrx component store attached? I'm having trouble doing this manually and there doesn't seem to be much traction on this topic |
Beta Was this translation helpful? Give feedback.
-
I think componentStore can handle this question? |
Beta Was this translation helpful? Give feedback.
-
Standalone Angular
Standalone Angular APIs are introduced in version 14. They make Angular modules optional. Check Angular repo for more info 👉
angular/angular#43784, angular/angular#45554
Angular Modules from NgRx packages
Angular modules are not just used to declare components or provide services. They are also used to configure various application and library functionalities. For example, we use the
EffectsModule.forRoot
method to provideActions
observable at the root level of an Angular application, initialize the effects runner, and register root effects. Therefore, importing root modules from other NgRx packages will configure their functionalities and/or provide services:Also, NgRx exposes APIs to register additional reducers and effects in feature modules:
Using NgRx Modules with Standalone Angular APIs
Root Angular modules from NgRx packages can be configured at the application level using the
importProvidersFrom
function from@angular/core
in the following way:The feature reducer and effects can be registered lazily in the route configuration for a specific feature:
Standalone NgRx APIs
We can provide a better developer experience in Standalone Angular applications by creating functions to configure NgRx packages. For example, instead of
StoreModule.forRoot
we can create a function namedconfigureStore
orprovideStore
. The same principle can be applied for other NgRx packages. Their usage would look like this:Feature effects and reducers would be also registered by using functions instead of NgModules:
Playground
The playground project is available here
Beta Was this translation helpful? Give feedback.
All reactions