添加逻辑到商店?

时间:2016-08-24 13:18:39

标签: javascript redux react-redux

我有一个带有"广告系列"的redux应用程序。减速器/存储。

目前,我已重复使用代码来检查是否已加载特定广告系列或需要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);

问题:这是一个很好的解决方案,还是redux-structure期望采用不同的模式来解决这个问题?

问题2 :我们应该向商店添加getter方法,例如store.campaign.getItem(myId)添加卫生设施(确保myId存在并加载,......)或者是否有不同的方法这在redux?

2 个答案:

答案 0 :(得分:3)

通常,计算组件应该负责执行此类逻辑。当然你的函数有一个复杂的条件检查,它完全属于你的计算组件(就像你现在拥有的那样)。

此外,redux仅用于维护状态。没有理由添加方法来查询reducers中当前状态的值。更好的方法是使用专门用于解析状态的模块。然后,您可以将状态传递给模块,它将提取相关信息。保持您的redux / store代码专注于仅计算状态。

答案 1 :(得分: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);