Redux reducers——改变深度嵌套状态
Redux reducers -- changing deeply-nested state
我正在努力思考如何在 redux 中更改深层嵌套状态。结合减速器并更改这些部分的状态的一级属性对我来说很有意义。我不太清楚的是如何改变深层嵌套的状态 属性。
假设我有一个购物车应用程序。以下是我的状态:
{
cart: {
items: []
},
account: {
amountLeft: 100,
discounts: {
redeemed: [],
coupons: {
buyOneGetOne: false
}
}
}
}
当用户输入代码时,假设他们可以兑换 "buyOneGetOne" 优惠券并且该值应该变为真。
我有一个用于购物车的减速器和另一个用于帐户的减速器。对于第一级 属性(比如我正在清理购物车的物品),我会在我的 reducer 中执行以下操作:
case 'EMPTY_CART':
return Object.assign({}, state, {items: []});
然而,为了改变 buyOneGetOne,我似乎需要先对优惠券进行 Object.assign(因为修改了 buyOneGetOne),然后对折扣进行 Object.assign(因为我修改了优惠券),然后最后发出操作,以便 reducer 可以在帐户上执行 Object.assign(因为折扣现在已经改变)。不过,这看起来真的很复杂而且容易出错,这让我相信一定有更好的方法。
我是不是做错了?似乎 reducers 只用于修改状态的根级属性(如购物车和帐户),我不应该有一个涉及帐户内部状态的 reducer(如折扣减速器),因为帐户已经有一个减速器.但是当我只想更改状态树中的一个 属性 时,合并从该更改一直到对象链上的每个对象到根的子对象变得很复杂...
可以you/should你在减速器内部有减速器吗,就像在这种情况下有折扣减速器?
你绝对可以在reducer里面有reducer;事实上,redux 演示应用程序是这样做的:http://redux.js.org/docs/basics/Reducers.html.
例如,您可以创建一个名为“discounts”的嵌套化简器:
function discounts(state, action) {
switch (action.type) {
case ADD_DISCOUNT:
return state.concat([action.payload]);
// etc etc
}
}
然后在您的账户缩减器中使用这个缩减器:
function account(state, action) {
switch (action.type) {
case ADD_DISCOUNT:
return {
...state,
discounts: discounts(state.discounts, action)
};
// etc etc
}
}
要了解更多信息,请观看 egghead.io redux series by Dan himself, specifically the reducer composition 视频!
你应该为每个深度嵌套 combinedReducers
是的,分离那些减速器是正确的。实际上,如果您担心其中一些操作需要更改其他 reducer,您可以对其他常量做出反应,或者只是派发另一个操作。
I've created a library 来解决这个问题——允许简单的组合,避免冗长的语法,以及合并结果。
因此,您的示例将如下所示:
import { createTile, createSyncTile } from 'redux-tiles';
const cartItems = createSyncTile({
type: ['account', 'cart'],
fn: ({ params }) => ({ items: params.items })
});
const coupons = createSyncTile({
type: ['account', 'coupons'],
fn: ({ params }) => params,
});
const reedemedCoupons = createSyncTile({
type: ['account', 'reedemedCoupons'],
fn: ({ params }) => params.coupons
});
const account = createTile({
type: ['account', 'info'],
fn: ({ api }) => api.get('/client/info')
});
使用这个策略每个组件都是原子的,你可以很容易地创建新组件和调度其他组件,而不影响其他组件,当你的 "tiles"单一职责原则。
我正在努力思考如何在 redux 中更改深层嵌套状态。结合减速器并更改这些部分的状态的一级属性对我来说很有意义。我不太清楚的是如何改变深层嵌套的状态 属性。 假设我有一个购物车应用程序。以下是我的状态:
{
cart: {
items: []
},
account: {
amountLeft: 100,
discounts: {
redeemed: [],
coupons: {
buyOneGetOne: false
}
}
}
}
当用户输入代码时,假设他们可以兑换 "buyOneGetOne" 优惠券并且该值应该变为真。 我有一个用于购物车的减速器和另一个用于帐户的减速器。对于第一级 属性(比如我正在清理购物车的物品),我会在我的 reducer 中执行以下操作:
case 'EMPTY_CART':
return Object.assign({}, state, {items: []});
然而,为了改变 buyOneGetOne,我似乎需要先对优惠券进行 Object.assign(因为修改了 buyOneGetOne),然后对折扣进行 Object.assign(因为我修改了优惠券),然后最后发出操作,以便 reducer 可以在帐户上执行 Object.assign(因为折扣现在已经改变)。不过,这看起来真的很复杂而且容易出错,这让我相信一定有更好的方法。
我是不是做错了?似乎 reducers 只用于修改状态的根级属性(如购物车和帐户),我不应该有一个涉及帐户内部状态的 reducer(如折扣减速器),因为帐户已经有一个减速器.但是当我只想更改状态树中的一个 属性 时,合并从该更改一直到对象链上的每个对象到根的子对象变得很复杂...
可以you/should你在减速器内部有减速器吗,就像在这种情况下有折扣减速器?
你绝对可以在reducer里面有reducer;事实上,redux 演示应用程序是这样做的:http://redux.js.org/docs/basics/Reducers.html.
例如,您可以创建一个名为“discounts”的嵌套化简器:
function discounts(state, action) {
switch (action.type) {
case ADD_DISCOUNT:
return state.concat([action.payload]);
// etc etc
}
}
然后在您的账户缩减器中使用这个缩减器:
function account(state, action) {
switch (action.type) {
case ADD_DISCOUNT:
return {
...state,
discounts: discounts(state.discounts, action)
};
// etc etc
}
}
要了解更多信息,请观看 egghead.io redux series by Dan himself, specifically the reducer composition 视频!
你应该为每个深度嵌套 combinedReducers
是的,分离那些减速器是正确的。实际上,如果您担心其中一些操作需要更改其他 reducer,您可以对其他常量做出反应,或者只是派发另一个操作。
I've created a library 来解决这个问题——允许简单的组合,避免冗长的语法,以及合并结果。 因此,您的示例将如下所示:
import { createTile, createSyncTile } from 'redux-tiles';
const cartItems = createSyncTile({
type: ['account', 'cart'],
fn: ({ params }) => ({ items: params.items })
});
const coupons = createSyncTile({
type: ['account', 'coupons'],
fn: ({ params }) => params,
});
const reedemedCoupons = createSyncTile({
type: ['account', 'reedemedCoupons'],
fn: ({ params }) => params.coupons
});
const account = createTile({
type: ['account', 'info'],
fn: ({ api }) => api.get('/client/info')
});
使用这个策略每个组件都是原子的,你可以很容易地创建新组件和调度其他组件,而不影响其他组件,当你的 "tiles"单一职责原则。