简体   繁体   English

Redux 在数组中存储嵌套数据的不可变模式?

[英]Redux store immutable pattern for nested data in array?

I've got a simple JSON data array that looks like this (it's the same in my Redux store and I store it under properties ):我有一个简单的 JSON 数据数组,看起来像这样(它在我的 Redux 商店中是相同的,我将它存储在properties下):

[
  {
    "id": "room",
    "name": "Room",
    "description": "Just a room",
    "foo": "bar",
  },
  {
    "id": "apartment",
    "name": "Apartment",
    "description": "just an apartment",
    "foo": "bar",
  }
]

It has to be an array because I'm mapping over it:它必须是一个数组,因为我正在映射它:

{properties.map(property => 
  <Property 
    id={property.id} 
    name={property.name} 
    description={property.description} 
    foo={property.foo}
 />)}

This way I have two properties rendered in my app.这样我在我的应用程序中呈现了两个属性。

The question is - how do I update "foo" in Redux?问题是 - 如何在 Redux 中更新"foo"

This my reducer currently written according to the docs :这是我目前根据文档编写的减速器:

case 'UPDATE_FOO':
  return {
    ...state, 
    properties: {
      ...state.properties,
      [action.id]: {
      ...state.properties[action.id],
      foo: action.fooData,
    }
  }
}

Of course it throws TypeError: Cannot read property 'room' of undefined because I'm trying to access state.properties["room"] and this does not exist.当然它会抛出TypeError: Cannot read property 'room' of undefined因为我试图访问state.properties["room"]而这不存在。

I've been thinking about reshaping my JSON and Redux store, but once I change it to named objects I can't map over it...我一直在考虑重塑我的 JSON 和 Redux 存储,但是一旦我将它更改为命名对象,我就无法映射它......

Thank you!谢谢!

Change your store to be an object, and generate the array, when you need to render it, by converting it to an array, using Object.values() :将您的商店更改为一个对象,并在需要渲染它时生成数组,方法是使用Object.values()将其转换为数组:

{Object.values(properties).map(property => (
  <Property key={property.id} {...property} />
)}

If the order might change (sorting for example), you need to have another array with the ids to hold the order (see redux normalized state ):如果订单可能会改变(例如排序),您需要有另一个带有 id 的数组来保存订单(请参阅redux normalized state ):

{
  properties: {
    room: {
      "id": "room",
      "name": "Room",
      "description": "Just a room",
      "foo": "bar",
    },
    apartment: {
      "id": "apartment",
      "name": "Apartment",
      "description": "just an apartment",
      "foo": "bar",
    }
  }
}

{
  properties: {
    room: {
      "id": "room",
      "name": "Room",
      "description": "Just a room",
      "foo": "bar",
    },
    apartment: {
      "id": "apartment",
      "name": "Apartment",
      "description": "just an apartment",
      "foo": "bar",
    }
  },
  order: ['apartment', 'room']
}
    
{order.map(id => (
  <Property key={id} {...properties[id]} />
)}

If you want to update the store using but the Id.如果您想使用但 Id 更新商店。 You can look up for the one element (you're trying to edit) in array of properties using the id, then to update it:您可以使用 id 在属性数组中查找一个元素(您正在尝试编辑),然后更新它:

    case 'UPDATE_FOO':
        const newProperties = state.properties.map(property => {
            if(property.id === action.id) {
                return { ...property, foo: action.fooData}
            }
            return property;
        })
        return {
            ...state,
            properties: newProperties
        }
     }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM