2016-08-24 94 views
2

我有一個「活動」減速機/商店的REDX應用程序。添加邏輯到商店?

目前我有重複的代碼來檢查是否加載了特定的廣告系列或需要API調用來從數據庫中獲取詳細信息。大大簡化它看起來像這樣:

// Reducer ---------- 
export default campaignReducer => (state, action) { 
    const campaignList = action.payload 
    return { 
     items: {... campaignList} 
    } 
} 

// Component ---------- 
const mapStateToProps = (state, ownProps) => { 
    const campaignId = ownProps.params.campaignId; 
    const campaign = state.campaign.items[campaignId] || {}; 

    return { 
     needFetch: campaign.id 
      && campaign.meta 
      && (campaign.meta.loaded || campaign.meta.loading), 
     campaign, 
    }; 
} 

export default connect(mapStateToProps)(TheComponent); 

現在我不喜歡重複複雜的條件needFetch。我也不喜歡在mapStateToProps函數中有這個複雜的代碼,我想要一個簡單的檢查。所以,我想出了這個解決方案:

// Reducer NEW ---------- 
const needFetch = (items) => (id) => { // <-- Added this function. 
    if (!items[id]) return true; 
    if (!items[id].meta) return true; 
    if (!items[id].meta.loaded && !items[id].meta.loading) return true; 
    return false; 
} 
export default campaignReducer => (state, action) { 
    const campaignList = action.payload 
    return { 
     needFetch: needFetch(campaignList), // <-- Added public access to the new function. 
     items: {... campaignList} 
    } 
} 

// Component NEW ---------- 
const mapStateToProps = (state, ownProps) => { 
    const campaignId = ownProps.params.campaignId; 
    const campaign = state.campaign.items[campaignId] || {}; 

    return { 
     needFetch: state.campaign.needFetch(campaignId), // <-- Much simpler! 
     campaign, 
    }; 
} 

export default connect(mapStateToProps)(TheComponent); 

問題:這是一個很好的解決方案,還是在終極版結構指望一個不同的模式來解決這個問題?

問題2:我們應該getter方法添加到店,喜歡store.campaign.getItem(myId)增加環衛(確保身份識別碼存在且被加載,..)或有在終極版此不同的做法?

回答

2

你的方法有點違背了對redux中狀態的習慣理解。 You should keep only serializable data in the state,不是功能。否則,你會失去redux的許多好處,例如您可以非常輕鬆地將應用程序的狀態隱藏到本地存儲中,或者從服務器保存它以恢復以前的會話。


相反,我會提取條件到一個單獨的庫文件,並將其導入必要的容器組件:

// needsFetch.js 
export default function needsFetch(campaign) { 
    return campaign.id 
      && campaign.meta 
      && (campaign.meta.loaded || campaign.meta.loading); 
} 

// Component ---------- 
import needsFetch from './needsFetch'; 

const mapStateToProps = (state, ownProps) => { 
    const campaignId = ownProps.params.campaignId; 
    const campaign = state.campaign.items[campaignId] || {}; 

    return { 
     needFetch: needsFetch(campaign), 
     campaign, 
    }; 
} 

export default connect(mapStateToProps)(TheComponent); 
+0

乾淨多了!我喜歡這個解決方案 - 它絕對是比我的嘗試更好的「減少」解決方案 – Philipp

3

通常計算組件應該負責做這種類型的邏輯。當然你的函數有一個複雜的條件檢查,它完全屬於你的計算組件(就像你目前擁有它的方式)。

此外,redux僅用於維護狀態。沒有理由添加方法來查詢您的reducer中當前狀態的值。更好的方法是有一個專門用於解析狀態的模塊。然後,您可以將狀態傳遞給模塊,並提取相關信息。保持你的redux/store代碼只專注於計算狀態。