Understanding a Simple React, React-Router and Redux Application in ES2015. Part 2

This is the third article in a series of posts on react, redux and webpack. Others:

  1. configuring webpack
  2. Understanding a simple react, redux and react-router app in es2015, part1.

Here, we will cover the routes configuration, the actions and all the react components starting from the Root.


If you remember from the last post, the Root component is called inside of index.js, the entry point to our app. It receives redux’s store and the browser history as props.

<Root store={store} history={history} />

If you open app/containers/Root.js you will see the same as configureStore, namely, a conditional to see what environment you are in. Let’s check out the dev version:

import React, { Component, PropTypes } from 'react';
import { Provider } from 'react-redux';
import DevTools from './DevTools';
import { Router } from 'react-router';
import routes from '../routes';

export default class Root extends Component {
    render() {
        const { store, history } = this.props;
        return (
            <Provider store={store}>
                    <Router history={history} routes={routes} />
                    <DevTools />

Root.propTypes = {
    store: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired

Lot’s of imports here:

  • from react we import the Component and PropTypes objects. The Component object is what we extend when creating a react component. The PropTypes object is used to reinforce types in our props, i.e. passing a string when an array was expected will throw a warning in the console. We also need the react lib itself, removing it will give an error.
  • The provider from react-redux is a utility higher-order component to make the store available to all components inside who wish to subscribe to it.
  • Devtools is the monitor we see when we run the app, docked on the right. It shows us the current and past states.
  • Router from react-router. This is the component where we will configure our app’s routes.
  • Routes are our app’s route. We will check them out later.

All our Root component does is wrap our app around the Provider component. We render the Router inside of it, along with the DevTools (if we are in a dev env).


Open up /app/routes.js. This is where you distribute your app into routes. It’s also the place where you decide what component goes with what route.

import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './components/App';
import FilterableTable from './containers/FilterableTable';
import About from './components/About';

export default (
	<Route path="/" component={App}>
		<IndexRoute component={FilterableTable} />
		<Route path="/about" component={About} />

Our app is pretty simple: our root path belongs to the App component. Then we have two routes inside of our root: and index and “/about”. This means whatever route we are in, “/” or “/about”, our App component will always render.

React will only render FilterableTable if we are in the root path “/”. The same logic applies to About.


Go to /app/components/App.js

import React, { PropTypes } from 'react';
import { Link } from 'react-router';

const App = ({ children }) =>
        <h1>Filter table</h1>
        { children }
            <Link to="/">Filterable Table</Link>
            <Link to="/about">About</Link>

App.PropTypes = {
    children: PropTypes.object

export default App;

If you’re asking yourself why our components are divided into the /components and /containers directories. Then have a look at this part of the redux docs. Basically, the components directory holds the “dumb” components, those that are not aware of redux and its store. They only receive props and care about presentation. The components inside /containers are aware of the app’s state as they are connected to the redux store.

This App component is available everywhere so it’s smart to put things like site navigation in here. That’s why we put a footer with the two routes we have. You must also pass in the children prop, which references the components that must be rendered inside the App for a given route.

If you navigated to “/about”, the children component will actually be the About component. React-Router, for good or bad, abstracts all of this. That’s why we must take care when we define our routes.


Open up /app/containers/FilterableTable.js

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { filterTable } from '../actions';
import ProductTable from '../components/ProductTable';

const FilterableTable = ({ filter, onFilter }) => {
    let input;

    return (
        <div className="filterable-table">
                ref={node => {input = node;}}
                onChange={() => onFilter(input.value)} />

            <ProductTable filter={filter} />

FilterableTable.propTypes = {
    filter: PropTypes.string,
    onFilter: PropTypes.func

const mapStateToProps = (state) => {
    return {
        filter: state.filter

const mapDispatchToProps = (dispatch) => {
    return {
        onFilter: filterText => dispatch(filterTable(filterText))

export default connect(

We import connect from react-redux. This function connects or subscribes a component to the store, making it aware of any changes to the state.

We also import filterTable from our actions. This function is really simple:

// app/actions/index.js

export function filterTable(filter) {
    return {
        type: types.FILTER,

It takes the current filter and return and action object with the action type and that filter. This action object gets sent to the reducer so the reducer can compute the next state.

We define a component called FilterableTable. It has an input where you can filter the ProductTable. Basically, whenever there’s a change in the filter, the state changes, so the ProductTable component reacts to that and changes accordingly.

It receives 2 props, filter and onFilter. Where are this props coming from? They are certainly not from the app component, nor from the router. They come from the connect function of react-redux. This function acts as a wrapper. Check out the last lines of FilterableTable. We are not exporting the FilterableTable component directly, we are actually exporting a wrapper of that component.

The wrapper takes 2 params when being created: mapStateToProps, and mapDispatchToProps.

With these 2 params, you can map which part of the state you want to make available to the component (FilterableTable), as well as which actions.

When we call connect(mapStateToProps, mapDispatchToProps) we are configuring the wrapper component, and we pass in what part of the state we want to know about, and which actions we want present so that we can dispatch them to the store.

When we do  connect(mapStateToProps,mapDispatchToProps)(FilterableTable);We are doing the above mentioned, configuring the wrapper component but also creating it by passing in the FilterableTable component. Internally, its probably dong something like this:

const connect (mapStateToProps, mapDispatchToProps) => {
    const filter = doSomethingThatGetsState(mapStateToProps);
    const onFilter = doSomethingThatGetsActions(mapDispatchToProps);

    return FilterableTable => class extends Component {
        render () {
            return (
                    onFilter={onFilter} />

In short: when dealing with containers, we export a wrapper function (i.e. the container) and pass in the component that should receive the state and callbacks it needs.

Note: Normally you would have the FilterableTable component in another file, under the components directory. You would only need to have the mappings and the connect in this file (basically the wrapper). I just like to have it on the same file to better understand what’s gong on, specially if it’s not too big.



import React, { PropTypes } from 'react';
import ProductRow from './ProductRow';

const products = [
  { category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football' },
  { category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball' },
  { category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball' },
  { category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch' },
  { category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5' },
  { category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7' }

const ProductTable = ({ filter }) => {
    let rows = [];

    products.forEach((p) => {
        const nameLC =;
        const filterLC = filter.toLowerCase();

        if (nameLC.indexOf(filterLC) !== -1) {
                <ProductRow key={} data={p} />

    return <div> {rows} </div>;

ProductTable.PropTypes = {
    filter: PropTypes.string

export default ProductTable;

This component’s only concern is to show the ProductRows that should be visible under the current filter. It does this by comparing the filter with every product name, using javascript’s indexOf function. It only pushes the matching ProductRows to the array that will later be used to show the products.

Note: the products array doesn’t really belong here, it should be in a database, but you already knew this.


import React, { PropTypes } from 'react';

const ProductRow = ({ data }) =>
        <p>{} = {data.price} </p>

ProductRow.PropTypes = {
    data: PropTypes.object

export default ProductRow;

Easy stuff, this component’s only concern is to show the product row: name and price.




Javascript jedi padawan.