Handling relational data in Redux

by Jordan Enev

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-0.14.6.js"></script>
<script src="https://fb.me/react-dom-0.14.6.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.3.1/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.6/react-redux.min.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/reselect.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<div id="root"></div>

JavaScript 1.7

const { Component } = React;
const { combineReducers, createStore } = Redux;
const { connect, Provider } = ReactRedux;
const { createSelector } = Reselect;

/**
 * Initial state for Books and Authors stores
 */
const initialState = {
	byIds: {},
  allIds:[]
 };

/**
 *	Book Action creator and Reducer
 */

const addBooks = payload => ({
	type: 'ADD_BOOKS',
	payload
})

const booksReducer = (state = initialState, action) => {
	switch(action.type) {
  	case 'ADD_BOOKS':
      let byIds = {}
      let allIds = []

      action.payload.map(entity => {
        byIds[entity.id] = entity
        allIds.push(entity.id)
      })
      
      return { byIds, allIds }
    default:
    	return state;
  }
};

/**
 *	Author Action creator and Reducer
 */

const addAuthors = payload => ({
	type: 'ADD_AUTHORS',
	payload
})

const authorsReducer = (state = initialState, action) => {
	switch(action.type) {
  	case 'ADD_AUTHORS':
      let byIds = {}
      let allIds = []

      action.payload.map(entity => {
        byIds[entity.id] = entity
        allIds.push(entity.id)
      })
      
      return { byIds, allIds }
    default:
    	return state;
  }
};

/**
 * Presentational components
 */
const Book = ({book}) => <div>{`Name: ${book.name}`}</div>
const Author = ({author}) => <div>{`Name: ${author.name}`}</div>


/**
 * Container components
 */
 
class View extends Component {
	componentWillMount() {
  	this.addBooks();
    this.addAuthors();
  }
  
  /**
   * Add dummy Books to the Store
 	 */
  addBooks() {
  	const books = [{
    	id: 1,
      name: 'Book 1',
      category: 'Programming',
      authorId: 1
    },{
    	id: 2,
      name: 'Book 2',
      category: 'Health',
      authorId: 2
    }];

		this.props.addBooks(books);
  }
  
  /**
   * Add dummy Authors to the Store
 	 */
  addAuthors() {
  	const authors = [{
    	id: 1,
      name: 'Jordan Enev',
      books: [1]
    },{
    	id: 2,
      name: 'Nadezhda Serafimova',
      books: [2]
   ...