向商店添加逻辑?
Add logic to the store?
我有一个带有 "campaign" reducer/store 的 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 结构需要不同的模式来解决这个问题?
问题 2:我们是否应该向商店添加 getter 方法,例如 store.campaign.getItem(myId)
添加卫生(确保 myId 存在并已加载,. .) 或者在 redux 中有不同的方法吗?
通常计算组件应该负责执行此类逻辑。确保您的函数具有复杂的条件检查,它完全属于您的计算组件(就像您当前拥有它的方式一样)。
另外,redux只是为了保持状态。没有理由添加方法来查询 reducer 中当前状态的值。更好的方法是拥有一个专门用于解析您的状态的模块。然后您可以将状态传递给模块,它会提取相关信息。让您的 redux/store 代码只专注于计算状态。
你的做法有点违背redux中state的惯用理解。 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);
我有一个带有 "campaign" reducer/store 的 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 结构需要不同的模式来解决这个问题?
问题 2:我们是否应该向商店添加 getter 方法,例如 store.campaign.getItem(myId)
添加卫生(确保 myId 存在并已加载,. .) 或者在 redux 中有不同的方法吗?
通常计算组件应该负责执行此类逻辑。确保您的函数具有复杂的条件检查,它完全属于您的计算组件(就像您当前拥有它的方式一样)。
另外,redux只是为了保持状态。没有理由添加方法来查询 reducer 中当前状态的值。更好的方法是拥有一个专门用于解析您的状态的模块。然后您可以将状态传递给模块,它会提取相关信息。让您的 redux/store 代码只专注于计算状态。
你的做法有点违背redux中state的惯用理解。 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);