如何使用 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 结合使用? 提前致谢。

解决方法

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"
}