Why you should NEVER use Redux with Angular
Preface: What is Redux?
Redux is a JavaScript library for managing application state. It was popularized by React because it solved the "extraneous props" issue and played well with flux architecture.
What is the extraneous props issue?
Like Angular, React generates UI components that fall within a “component hierarchy”. Parent components can pass data to child components by way of props. This is similar to how the @Input decorator works in Angular.
Check out this example to see how this works in React.
While this makes it possible for components to share data, it gets messy when you want to pass data 5-10 levels up or down the component tree. Components end up having “extraneous properties” that create unnecessary relationships with other components. This makes them less reusable.
What is Flux?
Flux is a design pattern popularized by React. It emphasizes unidirectional data flow and proved more performant than the two-way data binding popularized by AngularJS. In fact, the rewrite of Angular was largely influenced by Flux concepts. You can read more about Flux here.
Why You Should NOT Use Redux With Angular
While Redux solved a lot of problems with React, it’s use case doesn’t apply to Angular.
React is simply a UI component library. Angular is a highly opinionated framework around dependency injection (DI). This makes it easy to share state out of the box. Services can easily be shared across different component classes....
@Injectable()
export class AppStore {
userName: "Sam"
constructor() { }
}
export class Comp1 {
constructor(store:AppStore){
this.displayName = store.userName;
}
}
export class Comp2 {
constructor(store:AppStore){
this.userName = store.userName;
}
}
While you can achieve something similar with React, the easier option is to use Redux.
This is why Redux became so popular with React. It's the same way other third party libraries (like Axios) became popular with React. These libraries are necessary because React is simply a UI component library.
Just like Redux makes it easier to share state, Axios makes it easier to make Ajax requests.
And just like Angular doesn't need Axios because of it's own httpClientModule, it doesn't need Redux because of things like DI, services, and RxJS....
RxJS and Redux
RxJS is a library for making async requests. It leverages the observable design pattern to bring a reactive pub/sub functionality to Angular.
Using RxJS, Angular components can subscribe to event streams. This allows them to listen for data changes (events) over time.
So what does this have to do with Redux? It turns out Redux implements a similar pub/sub relationship between components and the store. Components subscribe to stores in Redux just like components subscribe to RxJS Observables in Angular.
For these reasons, you can argue that Redux is a redundant addition to Angular because Angular achieves the same behavior using RxJS.
Too Much Boilerplate
Redux works by dispatching defined "actions" that functions called "reducers" interpret to update a centralized "store". This tends to generate a lot of boilerplate code as your app grows and gets messy fast.
While Angular has its fair share of boilerplate, you don't need an excuse to add even more. Since using things like RxJS and shared services is a proven alternative, there is no need to further complicate your code base with a bunch of actions and reducers.
Conclusion
The Angular team put a lot of thought into component interaction and shared state. The framework already has everything you need to share state across different components. It's change detection strategy is super fast out of the box so don't worry about performance implications of cross-component interaction or immutability and OnPush.
Remember that Redux was an answer to React problems. And just like Angular doesn't need Axios, it doesn't need Redux...
Your thoughts?
Correct! Redux is a big no no with Angular. If you are using Redux with Angular then you don't understand the tools available to you when using Angular ecosystem/framework.
I am a hard core React developer and even I can say Redux is completely overkill for many use cases. Especially when you compare it to using React's more lightweight Context, Redux can overcomplicate rather simple implementations.
I am not as familiar with the Angular ecosystem but understand that they implement a "framework" versus a library. They probably do have robust ways of handling shared state out of the box.
I agree.
who uses Angular anyways :)
no sense in shaming someone if they want to use redux with Angular. No sense in shaming someone if they want to use @Injectable and avoid using external dependencies with an already robust framework that is Angular 2+...
great read thanks
From time to time I get really really triggered by some random internet post that gives me inner rage when reading it, starting with its unqualified clickbait title. This is one of these posts.
As a developer who knows both worlds and is capable of abstracting patterns I can just strongly disagree to this nonsense written in this post.
Usually I ignore posts where some internet dude is telling me exaggerations like "you will NEVER need..." or "you should NEVER use pattern x in framework y" because, as a well educated and quite battle tested dev, I do know that statements with "never", "always" and "only" tend to be mostly wrong.
Like that crap you are telling people here. As if the flux pattern does only solve the problem of sharing state between loosely coupled components. This is so vastly misunderstood with this pattern that most blog posts, stackoverflow answers and youtube videos just leave out some really important benefits of it.
At first to be mentioned: The distinct, deterministic and typable unidirectional data flow. This is the key part on redux, where state is immutable and only a reducer can emit a new state based on an action. Single point of truth for every state mutation, which - especially in large projects - makes maintenance a lot easier and component logic way easier testable... Don't know if OP ever tests his components.
Another point: Encapsulating side effects. Every state change is done by a reducer and only on foundation of an action that is distinct and well defined (even typed when you use redux toolkit for example - and yes you can use that in angular too with ngrx).
So lets imagine calling an api for data. Is that a synchronous task that can be described by a bidirectional flow of data? Well in the javascript world, it is not. Because in javascript most time consuming tasks (so done in many frames, not just in one blocking cycle) are by design asynchronous.
So when you call an api, you have two things that happen: First you start the call and the second thing is you wait for the event that provides the data. See? It is an asynchronous operation.
Retrieving the data is a side effect of dispatching a request to the api (server). And with redux you can beautifully encapsulate your side effects to the reducer which makes it possible to keep the whole application logic outside of your components, making them to just dumb components or view components that only display data and have just a minimum set of logic that is tightly coupled to them (eg. show class x when boolean y is true)
I am not talking about some fancy javascript animated websites with some runtime behaviour, I am talking about huge enterprise frontends with complex masks and behavior.
Encapsulation of side effects and bringing the whole application logic into reducer functions gives another great benefit that is often ignored by most javascript developers and script kiddies that tell other people to "nEvEr UsE tHiS aNd ThAt fOr tHiS aNd ThAt":
Multithreading in frontend applications. Most javascript developers tend to forget that most peoples' devices are between 3 and 5 years old and that there is a huge ermerging market for low budget, low edge mobile phones for less than 50 bucks which are capable of displaying web sites, but have a super slow single thread speed.
With redux you can easily bring the whole application logic into a web worker and keep the main thread clean and responsive for other task. My advice is to have a look here: https://github.com/GoogleChromeLabs/comlink
So saying someone should "NEVER" use redux in angular is stupid, short sighted and just wrong.
As I absolutely agree that using redux is an architectural decision that should be well planned and precisely justified, because of the complexity it comes with, I strongly disagree with this prohibiting statement that tells people just wrong things.
And let me tell you another no-brainer: You can share state between react components without redux as well. What hinders you in using rxjs in a react enviroment?
My advisoral conclusion to all the beginners struggling with some framework: There is no real right and wrong. If someone is telling you to "NEVER" or "ALWAYS" do something in a specific way they are usually wrong and the opposite is correct in most cases.
It's true that you don't need Redux to achieve shared state in Angular 2+. I would argue that it isn't necessarily "wrong" to use Redux with Angular. In fact, entire libraries exist for implementing Redux with Angular (ng-redux, etc).
If you are coming from a React background and are familiar with Redux and the concepts it introduces (actions, dispatchers, reducers, stores) then there is no reason why you can't apply these same concepts to an Angular project.
You can also just use an @Injectable service all the same. Similar to an application context in Spring Boot, Angular will create a shared container of dependencies that are used app wide.
Long story short, either is fine. I'd still consider this article a "win" because it definitely points out that you don't NEED to use something like Redux to manage shared state in Angular. This is not the same for React since you get into prop drilling hell pretty fast when you try to avoid using a shared state management tool like Redux.