Understanding the relationship between react, redux and react-redux

react and redux are basically independent libraries. You can use react without redux and redux without react. What glues both together is the react-redux library. I don't want to write a full blown tutorial about react and redux, so I'll keep it short.

Disclaimer: I'm not an expert. My explanations could be naïve ;)


react is obviously the library which renders the components to the DOM.


redux offers mechanisms to handle the state of your application.


react-redux is used to "connect" your React components to the store.
It has the 'Provider' component which makes your store available in its contained components (your app). It offers the "connect" method which has knowledge of this provided store. In your components you basically define all of your application state and actions in your props and don't access the store directly.

presentational and container components

In React it's usually a good pattern to separate your components into Presentational- and Container-Components - this can be achieved easily with Redux.
Your presentational component defines as props just what it's showing and not the source for a data aggregation.
An example would be the LogNotifier component:

interface LogNotifierProps {
    showError: boolean;
    subscribe: (subscriber: any) => void;
    unsubscribe: (subscriber: any) => void;

class LogNotifier extends React.Component<LogNotifierProps, {}> { … }

As you can see, the component itself doesn't define all log entries in the props to be able to figure out itself, if it should show a sign or not. Instead, it just defines showError. The mapStateToProps function which is used by the connect function of Redux, determines showError.

const mapStateToProps = (state: ApplicationState) => {
    return {
        showError: anyEntry(state.logTableState, "ERROR"),

const mapDispatchToProps = (dispatch: any) => {
    return {
        subscribe: (subscriber: any) => dispatch(logSubscribe(subscriber)),
        unsubscribe: (subscriber: any) => dispatch(logUnsubscribe(subscriber)),

const anyEntry = (state: LogTableState, logLevel: string): boolean => {
    for (var i = state.entries.length - 1; i >= 0; i--) {
        var entry = state.entries[i];

        if (logLevel.localeCompare(entry.Level.Name) === 0) {
            return true;

    return false;

export default connect(mapStateToProps, mapDispatchToProps)(LogNotifier);