2016-11-23 2 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の回答は、1か所でこれを行うことが余計なライブラリを保証しているとは思えなかったので、以下のように終わりましたが、これは非常に役に立ち、間違いなく私の次のプロジェクトの最初から実装されます!だから助けてくれてありがとう! – 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

関連する問題