还原在哪里进行计算?

meg*_*ams 3 javascript reactjs redux

一般问题,但将包括一个具体的例子:在哪里是循环通过状态/存储数据以提取计算的正确位置?

所以在这里,我需要进行一些计算,以显示在"统计数据"侧边栏中,该边栏需要循环遍历每个客户端阵列(可能是相当多的客户端)以提取不同的道具/值并将它们全部添加在一起.我在渲染中完成它只是为了使它工作,我知道是不正确的,但它是否仍然发生在组件和渲染之外或在reducer中?

值得注意的是,这些将是更新的值(客户端可以标记为"服务",然后统计信息侧栏将增加服务客户端的数量并减少要服务的客户端的数量).但这有点超出了我的一般问题的范围.

Hows和为什么非常感谢,感谢百万!

    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 (
          <div className="day-container">
            <aside className="column">
              <div className="statistics-bar-container">
                <h3 className="statistics-title">Statistics</h3>
                <ul className="statistics-items">
                  <li className="statistics-item">
                    <p>Clients expected</p>
                    <span>{stats.totalClientsExpected}</span>
                  </li>
                  <li className="statistics-item">
                    <p>Total household members to be served</p>
                    <span>{stats.totalHousehold}</span>
                  </li>
                  <li className="statistics-item">
                    <p>Served</p>
                    <span>{stats.totalServed}</span>
                  </li>
                  <li className="statistics-item">
                    <p>Did not show</p>
                    <span>{stats.totalNoShows}</span>
                  </li>
                  <li className="statistics-item">
                    <p>Unverified clients expected</p>
                    <span>{stats.totalUnverifiedExpected}</span>
                  </li>
                  <li className="statistics-item">
                    <p>Yet to be served</p>
                    <span>{stats.totalNotYetServed}</span>
                  </li>
                </ul>
              </div>
            </aside>
          </div>
        );
      }
    }

    function mapStateToProps(state) {
      return {
        clients: state.schedule.clients
      };
    }

    function mapDispatchToProps(dispatch) {
      return {
        actions: bindActionCreators(ScheduleActions, dispatch)
      };
    }

    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(ScheduleDayContainer);
Run Code Online (Sandbox Code Playgroud)

然后在reducer中:

    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;
      }
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ams 5

通常认为最佳做法是尽可能地将状态保持为规范化(想想关系数据库!).

您的派生数据可以通过称为选择器的辅助函数动态计算.如果其中一些计算费用昂贵,您可能需要考虑重新选择库.

一些阅读(抱歉,但他们解释得比我好!):

http://redux.js.org/docs/recipes/ComputingDerivedData.html

http://www.thinkloop.com/article/extreme-decoupling-react-redux-selectors/

https://medium.com/@adamrackis/querying-a-redux-store-37db8c7f3b0f#.gl7g9suh2