2016-11-23 101 views
1

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

所以在这里,我需要做一些计算,以显示在'stats'边栏中,需要通过每个客户端数组(可能是相当大数量的客户端)循环来提取不同的道具/值并添加他们都在一起。我只是为了让它工作而知道知道不正确,但它是否仍然发生在组件和渲染之外或还原器中?

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

很多赞赏和感谢,百万!

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); 

然后在减速:

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; 
     } 
    } 

回答

3

它普遍认为,要尽力保持状态标准化(认为关系数据库!)尽可能最佳实践。

您的推导数据可以通过称为选择器的帮助函数即时计算。如果其中一些计算结果昂贵,则可能需要考虑重新选择库。

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

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

+0

结束了@ Timo的回应,因为不确定是否在一个地方做了这个保证额外的库,但是,这是非常有帮助的,肯定会从我的下一个项目开始实施!所以感谢帮助! – megkadams

+0

不客气;祝一切顺利。 –

1

按照一般的做法,我也不会存储计算导致您的应用程序状态,而是在您的容器的步骤mapStateToProps中执行计算。

这也是the sample todo list application from the redux docs是继方法:

const getVisibleTodos = (todos, filter) => { 
    switch (filter) { 
    case 'SHOW_ALL': 
     return todos 
    case 'SHOW_COMPLETED': 
     return todos.filter(t => t.completed) 
    case 'SHOW_ACTIVE': 
     return todos.filter(t => !t.completed) 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
    todos: getVisibleTodos(state.todos, state.visibilityFilter) 
    } 
} 

计算过滤列表或你的国家做其他的计算是真的不从高层次的角度不同。


一旦使用在实践中遇到和性能问题的办法,你可以考虑一下缓存的结果无论是在国家还是在单独的缓存。但是,在实际面临任何问题之前优化此类only make your code more complex without real benefits

+0

感谢您的回应!这对我正在工作的范围以及解释非常有用非常有效。欣赏它! – megkadams