Redux in ReactJS
To say that Redux and ReactJS are closely linked is to state the understated. Redux was born from the Flux pattern which, like ReactJS itself, was developed by Facebook. Therefore, we should not be surprised at how much better developed the Redux implementation is on ReactjS vs Angular.
This is mainly done through the use of the react/redux NPM package. This single library allows you to utilize the connect method as a way to automatically wire React Components (called Containers in this context) to the store and listen for events. Example:
connect takes a couple parameters and returns a function which then takes the connected components. These parameters are the mapStateToProps and mapDispatchToProps. Through each of these methods we can define simple objects which create props that our component will receive.
This pattern is very easy, though can take some getting used to (more), but it offers a very easy way to bring elements of state into a component, as well as defining the methods that will dispatch actions to mutate state.
Redux in Angular
As a hard contrast to ReactJS, there is no single library for Angular, though a lot of the community has consolidated to using @ngrx/store. It actually does a very good job of aligning itself with what a developer that has Redux would expect.
Where I had the most difficulty was around properly defining the State Type here – I ended up going with the notion of global state but I realize now there are some better ways to go about this. Here is a sample of my current code:
In Typescript (which is the default language for Angular 2+) you can take an arbitrary JSON object and put an interface on top of it. This allow TS to be aware of what to expect from that object. If we go to the app.module.ts file which has the responsibility for setting up our store
We can see that our “store” defines an object with imagesTable property to which we have assigned our imagesReducer; this makes more sense if you view your reducers as being a “table” in the sense that it holds and manipulates only a certain segment of your data.
Now, as a rule, this really is a pure JSON object. GlobalState is an interface. As I said before, you can leverage interfaces as a means to give defined structure to JSON objects. Here is the definition of GlobalState:
The really important thing here is to make the connection of the properties defined for the store above and the properties of GlobalState. imageState here is simply the interface we placed on our reducer data, as defined through our initial state.
What happens with the store.select method is it gets passed the object we used in our StoreModel call within app.module. Then, using interfaces we can, effectively, “mask” this object to only see the state we wish to see; this is what gets passed into the select callback.
Thus, returning to our Component we can know understand this call better
Finally, as with most things in Angular 2+ we rely heavily on observables via the RxJS library; we do this in React as well using the redux-observables package, though that setup is slightly more complicated than Angular, which can leverage the built in support for observables, whereas React must rely on middleware, fore Redux anyway.
The one key point with observables in Angular, at least with those that are bound to the UI is that we must use the async directive to ensure the UI updates as the value within the observable changes.
Why I like React better?
In this example, I focused on the @ngrx/store library which seems to be what a lot of Angular developers are gravitating towards for their Redux. In React, this choice is already clear via the react/redux package and there are ample tutorials on how to set things up. With @ngrx/store there was not really a single good tutorial that I could find that would give me the step by step.
Further, I ran into breaking changes with @ngrx where I had to change things out as I went to build. This tells me the project is still very much under development and is still changing, as is Angular itself. I have not had the experience of running into such changes when dealing with react/redux.
The reality is, I wont truly recommend one over the other mainly because you can use both (React can be used as a view engine for Angular) and they are aimed at different purposes. I do feel the redux story is more refined with React but, that is not to say that Angular should be avoided, it just needs better docs and more maturation.