title: Where to do calculations in redux?
body: <p>General question, but will include a specific example: where is the correct place to loop through state/stored data to extract calculations?</p>
  
  <p>So here, I need to make some calculations to display in a 'stats' sidebar that requires looping through each of an array of clients (could be a rather large number of clients) to pull out different props/values and add them all together. I did it in render just to get it to work which I <em>know</em> is incorrect, but does it happen still in the component and outside of render or in the reducer?</p>
  
  <p>Of note, too, these will be updated values (a client can be marked as 'served' and then the stats sidebar will increment the number of served clients and decrement the number of to be served clients). But that is a little outside the scope of my general question.</p>
  
  <p>Hows and whys are much appreciated and thanks a million!</p>
  
  <pre><code>    import React, { Component, PropTypes } from 'react';
      import { browserHistory } from 'react-router';
      import './ScheduleDayContainer.scss';
      import { connect } from 'react-redux';
      import { bindActionCreators } from 'redux';
      import * as ScheduleActions from '../../actions/ScheduleActions';
  
      class ScheduleDayContainer extends Component {
        static propTypes = {
          actions: PropTypes.object,
          clients: PropTypes.array.isRequired
        };
  
        constructor(props, context) {
          super(props, context);
        }
  
        componentWillMount() {
          // gets schedule (code removed because doesn't matter here) and clients array (used below)
          this.props.actions.fetchDaySchedule();
        }
  
        render() {
          const { clients } = this.props;
  
          const getStats = function (clients) {
            let totalClientsExpected = clients.length,
                totalHousehold = clients.length,
                totalServed = 0,
                totalNoShows = 0,
                totalUnverifiedExpected = 0,
                totalNotYetServed = 0;
  
            clients.forEach(function(client) {
              totalHousehold += client.family_count;
              client.served_at != null ? totalServed += 1 : totalNotYetServed += 1;
              // TODO: no show?
              client.verified_at === null ? totalUnverifiedExpected += 1 : null;
            });
  
            return {
              totalClientsExpected,
              totalHousehold,
              totalServed,
              totalNoShows,
              totalUnverifiedExpected,
              totalNotYetServed
            };
          };
  
          const stats = getStats(clients);
  
          return (
            &lt;div className="day-container"&gt;
              &lt;aside className="column"&gt;
                &lt;div className="statistics-bar-container"&gt;
                  &lt;h3 className="statistics-title"&gt;Statistics&lt;/h3&gt;
                  &lt;ul className="statistics-items"&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Clients expected&lt;/p&gt;
                      &lt;span&gt;{stats.totalClientsExpected}&lt;/span&gt;
                    &lt;/li&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Total household members to be served&lt;/p&gt;
                      &lt;span&gt;{stats.totalHousehold}&lt;/span&gt;
                    &lt;/li&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Served&lt;/p&gt;
                      &lt;span&gt;{stats.totalServed}&lt;/span&gt;
                    &lt;/li&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Did not show&lt;/p&gt;
                      &lt;span&gt;{stats.totalNoShows}&lt;/span&gt;
                    &lt;/li&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Unverified clients expected&lt;/p&gt;
                      &lt;span&gt;{stats.totalUnverifiedExpected}&lt;/span&gt;
                    &lt;/li&gt;
                    &lt;li className="statistics-item"&gt;
                      &lt;p&gt;Yet to be served&lt;/p&gt;
                      &lt;span&gt;{stats.totalNotYetServed}&lt;/span&gt;
                    &lt;/li&gt;
                  &lt;/ul&gt;
                &lt;/div&gt;
              &lt;/aside&gt;
            &lt;/div&gt;
          );
        }
      }
  
      function mapStateToProps(state) {
        return {
          clients: state.schedule.clients
        };
      }
  
      function mapDispatchToProps(dispatch) {
        return {
          actions: bindActionCreators(ScheduleActions, dispatch)
        };
      }
  
      export default connect(
        mapStateToProps,
        mapDispatchToProps
      )(ScheduleDayContainer);
  </code></pre>
  
  <p>And then in the reducer:</p>
  
  <pre><code>    export default function scheduleReducer(state = initialState, action) {
        switch (action.type) {
          case types.FETCH_DAY:
            return {
              ...state,
              clients: action.data.clients,
              daySummary: action.data.summary,
              times: action.data.times,
              serviceDate: action.data.serviceDate,
              time: action.data.time
            };
          default:
            return state;
        }
      }
  </code></pre>