从嵌套的 redux 状态中移除元素
Remove element from nested redux state
我想从我的 redux 状态中删除一个元素。我正在使用 seamless-immutable 及其 API 来对状态进行操作。但是当状态嵌套时,我找不到任何漂亮的方法来删除元素。
所以我要删除的元素是:
state.shoppingcartReducer.products[articleNr]
谢谢!
import Immutable from 'seamless-immutable'
import { addToShoppingcart, createShoppingCart } from '../actions/shoppingcartActions'
const CREATE_SHOPPING_CART = 'CREATE_SHOPPING_CART'
const ADD_PRODUCT = 'ADD_PRODUCT'
const DELETE_PRODUCT = 'DELETE_PRODUCT'
const UPDATE_QUANTITY = 'UPDATE_QUANTITY'
const SUMMARY = 'SUMMARY'
const initialState = Immutable({
summary: {
sum: 0,
quantity: 0
}
})
export default function shoppingcartReducer(state = initialState, action) {
switch (action.type) {
case ADD_PRODUCT:
return state
.setIn(['products', action.product.articleNr], addArticle(action))
// case DELETE_PRODUCT:
// return ??
case SUMMARY:
return state
.set('summary', calculateSums(action, state))
case CREATE_SHOPPING_CART:
return state
.set(action.id, createCart(action))
case UPDATE_QUANTITY:
return state.
set('summary', calculateQuantity(action, state))
}
return state
}
function addArticle(action) {
return {
product: action.product
}
}
function calculateQuantity(action, state) {
return {
quantity: state.summary.quantity + action.quantity
}
}
function calculateSums(action, state) {
return {
sum: state.summary.sum + action.price,
quantity: state.summary.quantity + action.quantity
}
}
function calculateSumsDelete(action, state) {
return {
sum: state.summary.sum - action.product.price,
quantity: state.summary.quantity - action.product.quantity
}
}
function createCart(action) {
return {
id: action.id,
}
}
我以前也遇到过类似的情况。
所以根据 redux docs 更新嵌套对象的方式是:-
function updateVeryNestedField(state, action) {
return {
....state,
first : {
...state.first,
second : {
...state.first.second,
[action.someId] : {
...state.first.second[action.someId],
fourth : action.someValue
}
}
}
}
}
但是因为你的状态中有数组,所以你的工作有点困难。
所以有两种方法可以做到这一点。
第一种方式(艰难的方式)
自己创建一个新对象并更新状态,return 新状态。现在这里的关键是创建一个新的状态对象,而不是将您当前的状态分配给新对象,否则它会发生变化。
所以,创建一个新对象。
const newState ={}
现在为您分配您不想更改为新状态的当前状态值。假设在您的状态下您有 3 个键,key1
,您不希望此操作更改的 key2
和您想要更改的 shoppingCardReducer
。
newState['key1']=//key1 value from current state
newState['key2'] = //key2 value from current state
现在,尝试以下操作:-
newState['shoppingCardReducer'] ={}
newState['shoppingCardReducer']['products']={}
现在阅读 state.shoppingReducers.products
并开始循环遍历您的产品数组并替换状态中的特定元素,保持其余不变。
然后 return 新状态(您应该保持其余属性完好无损,否则您的应用程序可能会崩溃)
如果您发现这显然是一种糟糕的方法,而不是真正的 hack,reducer 会使用 spread 运算符做同样的事情,但肯定是不好的 way.So 我会说尝试下一个选项。
第二种方式(immutablejs)
我建议您使用 immutable.js。使用起来非常简单干净。
通过不可变,您可以使用 deleteIn
函数从您的状态中删除特定的特定产品元素。
data.deleteIn(["shoppingcartReducer",product,//your_to_deleted_element_index])
P.S:我还没有尝试过上面的代码,但稍加修改就可以了。我希望你明白逻辑。
第三种方法(Normalizr)
您也可以尝试对 normalize 做出您的 API 响应,使您的数据平坦并访问访问。
不过以上三者中我觉得immutable是最好的选择
您可以简单地使用删除方法:
删除this.props.register_reducer.selected_products['yourid'];
我想从我的 redux 状态中删除一个元素。我正在使用 seamless-immutable 及其 API 来对状态进行操作。但是当状态嵌套时,我找不到任何漂亮的方法来删除元素。
所以我要删除的元素是:
state.shoppingcartReducer.products[articleNr]
谢谢!
import Immutable from 'seamless-immutable'
import { addToShoppingcart, createShoppingCart } from '../actions/shoppingcartActions'
const CREATE_SHOPPING_CART = 'CREATE_SHOPPING_CART'
const ADD_PRODUCT = 'ADD_PRODUCT'
const DELETE_PRODUCT = 'DELETE_PRODUCT'
const UPDATE_QUANTITY = 'UPDATE_QUANTITY'
const SUMMARY = 'SUMMARY'
const initialState = Immutable({
summary: {
sum: 0,
quantity: 0
}
})
export default function shoppingcartReducer(state = initialState, action) {
switch (action.type) {
case ADD_PRODUCT:
return state
.setIn(['products', action.product.articleNr], addArticle(action))
// case DELETE_PRODUCT:
// return ??
case SUMMARY:
return state
.set('summary', calculateSums(action, state))
case CREATE_SHOPPING_CART:
return state
.set(action.id, createCart(action))
case UPDATE_QUANTITY:
return state.
set('summary', calculateQuantity(action, state))
}
return state
}
function addArticle(action) {
return {
product: action.product
}
}
function calculateQuantity(action, state) {
return {
quantity: state.summary.quantity + action.quantity
}
}
function calculateSums(action, state) {
return {
sum: state.summary.sum + action.price,
quantity: state.summary.quantity + action.quantity
}
}
function calculateSumsDelete(action, state) {
return {
sum: state.summary.sum - action.product.price,
quantity: state.summary.quantity - action.product.quantity
}
}
function createCart(action) {
return {
id: action.id,
}
}
我以前也遇到过类似的情况。
所以根据 redux docs 更新嵌套对象的方式是:-
function updateVeryNestedField(state, action) {
return {
....state,
first : {
...state.first,
second : {
...state.first.second,
[action.someId] : {
...state.first.second[action.someId],
fourth : action.someValue
}
}
}
}
}
但是因为你的状态中有数组,所以你的工作有点困难。
所以有两种方法可以做到这一点。
第一种方式(艰难的方式)
自己创建一个新对象并更新状态,return 新状态。现在这里的关键是创建一个新的状态对象,而不是将您当前的状态分配给新对象,否则它会发生变化。
所以,创建一个新对象。
const newState ={}
现在为您分配您不想更改为新状态的当前状态值。假设在您的状态下您有 3 个键,key1
,您不希望此操作更改的 key2
和您想要更改的 shoppingCardReducer
。
newState['key1']=//key1 value from current state
newState['key2'] = //key2 value from current state
现在,尝试以下操作:-
newState['shoppingCardReducer'] ={}
newState['shoppingCardReducer']['products']={}
现在阅读 state.shoppingReducers.products
并开始循环遍历您的产品数组并替换状态中的特定元素,保持其余不变。
然后 return 新状态(您应该保持其余属性完好无损,否则您的应用程序可能会崩溃)
如果您发现这显然是一种糟糕的方法,而不是真正的 hack,reducer 会使用 spread 运算符做同样的事情,但肯定是不好的 way.So 我会说尝试下一个选项。
第二种方式(immutablejs)
我建议您使用 immutable.js。使用起来非常简单干净。
通过不可变,您可以使用 deleteIn
函数从您的状态中删除特定的特定产品元素。
data.deleteIn(["shoppingcartReducer",product,//your_to_deleted_element_index])
P.S:我还没有尝试过上面的代码,但稍加修改就可以了。我希望你明白逻辑。
第三种方法(Normalizr)
您也可以尝试对 normalize 做出您的 API 响应,使您的数据平坦并访问访问。
不过以上三者中我觉得immutable是最好的选择
您可以简单地使用删除方法:
删除this.props.register_reducer.selected_products['yourid'];