从嵌套的 redux 状态中删除元素 [英] Remove element from nested redux state

查看:26
本文介绍了从嵌套的 redux 状态中删除元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从我的 redux 状态中删除一个元素.我使用无缝不可变及其 API 对状态进行操作.但是当状态嵌套时,我找不到任何好看的方法来删除元素.

I want to remove a element from my redux state. Im using seamless-immutable and its API to operate on the state. But I couldn't find any nice looking way to delete a element when the state is nested.

所以我要删除的元素是:state.shoppingcartReducer.products[articleNr]

So the element I want to delete is: 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,
  }
}

推荐答案

我以前也遇到过类似的情况.

I was stuck in a similar situation sometime back.

所以根据 redux docs 更新嵌套对象的方式是:-

So according the redux docs the way you update nested object is :-

function updateVeryNestedField(state, action) {
    return {
        ....state,
        first : {
            ...state.first,
            second : {
                ...state.first.second,
                [action.someId] : {
                    ...state.first.second[action.someId],
                    fourth : action.someValue
                }
            }
        }
    }
}

但是由于您的状态中有数组,因此您的工作会变得更加困难.

But since you have array in your state it makes you work bit more difficult.

所以有两种方法可以做到这一点.

So there are 2 ways in which you can do this.

第一种方式(艰难的方式)

自己创建一个新对象并更新状态并返回新状态.现在这里的关键是创建一个新的状态对象,而不是将您当前的状态分配给新对象,否则它会发生变异.

Create a new object on your own and update the state and return the new state. Now the key here to create a new state object and not assign your current state to the the new object else it would be mutated.

所以,创建一个新对象.

So, create a new object .

const newState ={}

现在为您分配您不想更改为新状态的当前状态值.假设在您的状态下,您有 3 个键,key1key2,您不想更改此操作,而 shoppingCardReducer 是您想要更改的.

Now assign you current state values which you dont want to change to the new state. Say in your state you have 3 keys , key1, key2 which you dont want this action to change and shoppingCardReducer which you want to change.

newState['key1']=//key1 value from current state
newState['key2'] = //key2 value from current state

现在,请尝试以下操作:-

Now, try following:-

newState['shoppingCardReducer'] ={}
newState['shoppingCardReducer']['products']={}

现在阅读 state.shoppingReducers.products 并开始遍历您的 products 数组并从 state 中替换该特定元素,保持rest不变.

Now read state.shoppingReducers.products and sttart looping over your products array and replace that particular element from the state, keep rest intact.

然后返回新状态(您应该保持其余属性完好无损,否则您的应用程序可能会中断)

Then return the new state(You should keep rest of properties intact else your app can break)

如果您认为这显然是一种糟糕的方法,而不是真正的 hack,reducers 与扩展运算符做同样的事情,但肯定是一种糟糕的方式.所以我会说尝试下一个选项.

If you see this is clearly a bad way to do it, not really a hack, reducers do same thing with spread operator but surely a bad way.So I would say try out next option.

第二种方式(immutablejs)

我建议您使用 immutable.js.使用起来非常简单和干净.

I would suggest you to use immutable.js. Its really easy and clean to use .

使用 immutable,您可以使用 deleteIn 函数从状态中删除特定的特定产品元素.

With immutable you can use deleteIn function to remove your particular particular product element from your state.

data.deleteIn(["shoppingcartReducer",product,//your_to_deleted_element_index])

P.S:我还没有尝试过上面的代码,但稍加修改它应该可以工作.我希望你明白逻辑.

P.S: I havent tried the above code but with little modification it should work. I hope you get the logic.

第三种方法(Normalizr)

您还可以尝试规范化您的 API 响应,以使您的数据扁平化和访问权限.

You can also try make to normalize your API response to make your data flat and access to access.

但在以上三个中,我觉得不可变是最好的选择.

But among above three I feel immutable is the best option.

这篇关于从嵌套的 redux 状态中删除元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆