首页 > 解决方案 > 如何使用 normalizr 规范化来自 JSON 的数据?

问题描述

我对 normalizr 很陌生,还不能很好地理解它。如何规范化以下 JSON 响应,使其可用于 Redux:

{
    "statusCode":200,
    "message":"Random quotes",
    "pagination":{
          "currentPage":1,
          "nextPage":null,
          "totalPages":1
        },
    "totalQuotes":1,
    "data":[
        {
          "_id":"5eb17aadb69dc744b4e70e05",
          "quoteText":"One crowded hour of glorious life is worth an age without a name.",  
          "quoteAuthor":"Walter Scott",
          "quoteGenre":"age",
          "__v":0
        }
    ]
}

将数据对象放在规范化对象的顶层会很有用。如何将它与 TypeScript 结合使用?先感谢您。

标签: reactjsreact-nativereduxreact-reduxnormalizr

解决方案


Typescript 类型绝对可以帮助您理解您正在处理的数据。您想用自己的类型来描述响应的各个部分,然后将它们拼凑在一起。

interface Quote {
  _id: string;
  quoteText: string;
  quoteAuthor: string;
  quoteGenre: string;
  __v: number;
}

interface Pagination {
  currentPage: number;
  nextPage: null | number; // what is this when it's not null?
  totalPages: number;
}

interface APIResponse {
  statusCode: number;
  message: string;
  pagination: Pagination;
  totalQuotes: number;
  data: Quote[];
}

normalizr在这里不是很有帮助,因为您只有一个实体类型,即Quote. 从某种意义上说,如果您将响应本身视为一个实体,那么您有两种实体类型。但我不确定您将如何从中提取唯一 ID。您可能必须根据 API 路径/参数自己添加它,因为 JSON 中缺少该信息。

const quote = new schema.Entity("quote", {}, { idAttribute: "_id" });

const response = new schema.Entity("response", {
  data: [quote] // an array of quote entities
});

console.log(normalize({...json, id: "/random-quote"}, response));

这给你

{
  "entities": {
    "quote": {
      "5eb17aadb69dc744b4e70e05": {
        "_id": "5eb17aadb69dc744b4e70e05",
        "quoteText": "One crowded hour of glorious life is worth an age without a name.",
        "quoteAuthor": "Walter Scott",
        "quoteGenre": "age",
        "__v": 0
      }
    },
    "response": {
      "/random-quote": {
        "statusCode": 200,
        "message": "Random quotes",
        "pagination": {
           "currentPage": 1,
           "nextPage": null,
           "totalPages": 1
        },
        "totalQuotes": 1,
        "data": ["5eb17aadb69dc744b4e70e05"],
        "id": "/random-quote"
      }
    }
  },
  "result": "/random-quote"
}

推荐阅读