At Redux’s Home Page, it says that Redux is a predictable state container for Javascript apps. Actually Typescript too if you’re using Angular2+. Both React and Angular have support for Redux. I’ve used it in a production Angular2 app at work.
Supposing you have a page that looks like this. The highlighted parts would represent individual components.

On the left hand side you an artist list that contains artist buttons. When you click on one of the artist buttons, it would be nice to see the details of their discography show up in the “Selected Artist”-component without having any directly connected dependencies from one component to another. In the days of Silverlight, this was accomplished with Prism (and it a pub/sub model). It entails broadcasting a “message” and “interested” parties can act on that message to update themselves.
So where does Redux come into this? In addition to that, what role does React and Angular play into it? Redux is all about the data within the application. React/Angular is all about the views that presents the data. So Redux really is the “one stop shop” for all of the data that comprises the app. This data can be the actual persistant data (ie, the artists, the discography, etc..) as well as data that is transient (such as the “currently selected artist”, etc..).
And re-iterating, React/Angular are the views that will adapt the data to something that can be displayed within the views.
With Redux, the application’s data becomes centralized inside of a single object. This object is referred to as the “application state” (the global object). Redux will contain the state of the application (data) that will be used by the views to determine what and how they should present themselves.
Redux will greatly simplify your application by allowing you to decouple your components from one another. It’s almost like having a token ring network where your individual nodes are your components. One (or more) of the nodes can update data on a global token (which represents the “state of the whole network ” in this *network* example (but it would represent the state of your whole app when you’re developing with it). which gets passed around to each node. A certain node (if interested) can use the data on the token to render itself as needed. And in turn, each node can update that token as needed to make it available to other nodes on the network. The beauty of that is none of the nodes really need to be aware of the other nodes. In addition, your application becomes cleaner because all of your applications data is sitting in one object rather than being scattered all over the place.
With Redux, you’re able to seperate your app into a container of data and a container of views.
Here’s a free course that you can take on egghead.io that will get you started with Redux. It was created by the creator of Redux.
Some key terms:
Reducer – A function that returns a part (values) of the “application state”. The application can have many “parts” of the application state. As such, it’s common for an application to have several reducers. In the above example, you could have a reducer for handling the “artist list” and one for handling “selected artist”. So in the above, you could have:
// application state
{
artists: [{name: 'Kansas'}, {name: 'Led Zeppelin'}, ...],
selectedArtist: {name: 'Kansas', albums: [{name: 'Kansas - 1974'}, ...],
...
...
}
Container – a React (or Angular) component that has a direct tie to the state that Redux is managing. It acts as a bridge between the application data and the application views. Whenever the application state changes, the container will automatically re-render.
In react, by using the redux function
import { connect } from 'react-redux';
class ArtistList extends Component {
..
render() {
// you can use this.props.artists here.
}
}
export default connect(mapTheStateToProps, mapTheDispatchToProps)(ArtistList);
You are taking the “ArtistList” component and a reducer function and turning the ArtistList component to a “container” for redux to manage.
Your reducer function would look like
function mapTheStateToProps(state) {
// Critical to understand
// If our application state ever changes,
// this container/component(ArtistList) will instantly re-render with a
// new list of artists
//
// whatever gets returned from here will show up as "this.props" inside
// of the ArtistList component
return {
// We want the value to be the list of artists off our main
// application state coming in
artists: state.artists
};
}
actions – Allow you to change the state of your application such that Redux will trigger a call to all reducer functions. Actions can be created when the user interacts with the UI (ie, button clicks, selecting an item in a list, etc..) or indirectly within the application (ie, such as when a REST call completes, etc..). In all cases, the reducer functions will be called. An action is basically an object that visits all of the reducers. Reducers can then use any action to construct a different value for it’s particular section of state.
action creator – A function that will return an “action”
In this case, we will call the action creator when we click on a specific artist.
function artistSelectionCreator () {
return {
type: ARTIST_SELECTED, // describe the action to be triggered.
artist: { name: selectedArtist } // the payload for the action
}
}
and the above (and all actions) action will be sent to all reducers by Redux.
The code for the reducer of the Selected artist would look like:
//
// all reducers get these 2 args
// the currentState refers to ONLY the part of the application state
// that the reducer subscribed for.
// Upon application startup, currentState could be undefined. Redux
// does not like that. To handle that case, set it to null instead.
export default function(currentState = null, action) {
switch (action.type) {
case ARTIST_SELECTED:
// this will be the new value
// of the "selectedArtist" in the application state since
// the SelectedArtist reducer was wired up to the "selectedArtist"
// key in the application state.
return action.artist;
...
default:
// this action is not important to this particular reducer so do
// nothing.
return currentState;
}
The other reducers will still get the action but can ignore it, etc..
When the reducers modify the application state, it will cause all of the container components to re-render themselves (with the new values of state available in the “this.props” in each container.
The function:
// what this function returns can be accessed thru the "props" object on
// the ArtistList container.
function mapTheDispatchToProps(dispatch) {
// dispatch is a function that is responsible for passing this (and all actions for that matter)
// action to all of the reducers in the app.
// "bindActionCreators" Redux method will ensure that when "selectArtist" is called,
// the result of that function will go thru the "dispatch" function.
// In our container, we can call 'this.props.selectArtist()' and
// that will call our action creator.
return bindActionCreators({ selectArtist: selectArtistInFunction}, dispatch);
}
is wired up above in the Redux “connect(..)” method like so.
export default connect(mapTheStateToProps, mapTheDispatchToProps)(ArtistList);
To call the action in a click handler for example:
renderArtists() {
return this.props.artists.map((artist)=>{
return (
<li key={artist.name}
onClick={()=>this.props.selectArtist(artist)}
className="artist-item">{artist.name}</li>
);;
});
}
this is what our action creator will look like (in a seperate file usually under an ‘actions’ folder. Recall that this function was linked up in the “mapTheDispatchToProps()” above within the call to the Redux “connect()” function.
// action creator
// export so we can make use in other parts of the app
export function selectArtistInFunction(artist) {
// selectArtistInFunction() is an action creator that returns an action.
// The action will be an object that has a "type" prop.
// The action ends up running thru all of our reducers.
// return our action
return {
// need a type that describes the meaning of the action
type: ARTIST_SELECTED // constant defined in a consts file
// payload for the action
payload: artist
}
}
In summary, the user clicks on the “select artist button” which invokes
onClick={()=>this.props.selectArtist(artist)}
“selectArtist” was wired up here
return bindActionCreators({ selectArtist: selectArtistInFunction}, dispatch);
which means that “selectArtist” is available on the “props” object of the ArtistList container as ‘this.props.selectArtist’. And that maps to the selectArtistInFunction() within the action creator. That in return will return an “action” that contains a type and a payload. Redux will ensure that action flows thru all of the reducers in the app. Each reducer will have a chance to act on that particular action (or ignore it if they chose to do so). If the reducer returns something other than the “currentState”, what gets returned will change the “specific” part of the application state that the reducer’s container was wired up to. By specific part, the “ArtistList” container above in the “mapTheStateToProps” affects the “selectedArtist” portion of application state.
I don’t claim to be an expert in React or Redux. I was just trying to convey my understanding of how the basic functionality of Redux works in a React app. I have used Redux in a production Angular2+ application and it works well. It really cleaned up the code and allowed for a clean seperation of data and views. You can have many views subscribing to changes to the same piece of data. Your application data is stored in a global “application state” logic. As a freebie, chrome gives you nice Redux extension that allows you to inspect your application state as it changes, etc… Before Redux, there was Flux. Flux, however, did not centralize your apps state in a single object. You had multiple stores to contend with, etc.. Redux seems to be a much more clean approach.