Redux 对象数组的 Normalizr 模式

dan*_*ads 1 normalization reactjs redux normalizr

我的 api 的当前响应如下:

[
   {  
      "device_id": "1234",
      "network_status": "Offline",
      "status": "Yes",
      "frequency": 50,

   },
   {  
      "device_id": "12345",
      "network_status": "online",
      "status": "no",
      "frequency": 123,

   },
   {  
      "device_id": "12346",
      "network_status": "online",
      "status": "no",
      "frequency": 423,

   },
]
Run Code Online (Sandbox Code Playgroud)

使用最新文档: https://github.com/paularmstrong/normalizr/blob/master/docs/api.md#arraydefinition-schemaattribute

我知道这些文档已经更新,因此查看堆栈上的其他问题我无法找到类似的示例。“responseData”包含来自 api 的响应,它是一个对象数组。[{},{},...]

我的代码是

import { schema } from 'normalizr';

const deviceid = new schema.Entity('device_id');
const arrayOfDevices = new schema.Array({
  device_id : deviceid,
})

normalize(responseData, arrayOfDevices)
Run Code Online (Sandbox Code Playgroud)

我想得到以下输出。将 device_id 作为每个对象的键的实体对象。

  {
  entities: {
    device_id: { 
      '1234' : {
        .....
      },
      '12345' : {
        .....
      } ,
      '123456' : {
        .....
      }
    }
  },
  result: [
    ['1234','12345','123456'],
  ]
}
Run Code Online (Sandbox Code Playgroud)

然而,我似乎只是得到了以下带有空实体的响应,并且其他所有内容都被推入结果中

 {
  entities: {},
  result: [
   {  
      "device_id": "1234",
      "network_status": "Offline",
      "status": "Yes",
      "frequency": 50,

   },
   {  
      "device_id": "12345",
      "network_status": "online",
      "status": "no",
      "frequency": 123,

   },
   {  
      "device_id": "12346",
      "network_status": "online",
      "status": "no",
      "frequency": 423,

   },
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的 Normalizr 代码似乎缺少什么?

tri*_*ixn 6

Normalizr 希望您的实体拥有一个idprop。如果包含 id 的字段有另一个名称,则必须显式定义它:

import { normalize, schema } from 'normalizr';

const data = [
  {
    "device_id": "1234",
    "network_status": "Offline",
    "status": "Yes",
    "frequency": 50,

  },
  {
    "device_id": "12345",
    "network_status": "online",
    "status": "no",
    "frequency": 123,

  },
  {
    "device_id": "12346",
    "network_status": "online",
    "status": "no",
    "frequency": 423,

  },
];

const device = new schema.Entity('devices', {}, { idAttribute: 'device_id' });

const normalizedData = normalize(data, [device]);

console.log(normalized);
Run Code Online (Sandbox Code Playgroud)

输出:

{
    "entities": {
        "devices": {
            "1234": {
                "device_id": "1234",
                "network_status": "Offline",
                "status": "Yes",
                "frequency": 50
            },
            "12345": {
                "device_id": "12345",
                "network_status": "online",
                "status": "no",
                "frequency": 123
            },
            "12346": {
                "device_id": "12346",
                "network_status": "online",
                "status": "no",
                "frequency": 423
            }
        }
    },
    "result": [
        "1234",
        "12345",
        "12346"
    ]
}
Run Code Online (Sandbox Code Playgroud)

编辑 w0z95yy8zl

还可以与normalizr 文档中的这个示例进行比较。

我建议不要命名 id 字段,device_id因为如果您正确命名保存实体的变量,那么这通常是多余的。例如,如果您有一系列设备,您应该为其命名devices。那么很明显,id里面的对象的字段就是设备id。无需在属性名称中重复该内容。