Skip to content

Normalizr 中文文档(未完待续...) #4

@collinxz-coder

Description

@collinxz-coder

目录

介绍

动机

很多 API 接口(无论是否公开)都返回多层嵌套的 JSON 数据。对于 JavaScript 应用程序来说,使用这些嵌套数据通常很麻烦,尤其是在那些使用了 Flux 或者 Redux 的应用中。

解决方案

Normalizr 是一个小巧且强大的工具,它通过 schema 来获取 JSON,并使用 id 返回其嵌套实体。这些实体存储在字典中。

Normalizr 就是一个数据范式化工具。

例子

下面是接口返回的嵌套数据:

[
  {
    id: 1,
    title: 'Some Article',
    author: {
      id: 1,
      name: 'Dan'
    }
  },
  {
    id: 2,
    title: 'Other Article',
    author: {
      id: 1,
      name: 'Dan'
    }
  }
];

使用 Normalizr 范式化后的数据:

{
  result: [1, 2],
  entities: {
    articles: {
      1: {
        id: 1,
        title: 'Some Article',
        author: 1
      },
      2: {
        id: 2,
        title: 'Other Article',
        author: 1
      }
    },
    users: {
      1: {
        id: 1,
        name: 'Dan'
      }
    }
  }
}

快速开始

考虑下一个典型的博客文章。获取一篇文章的 API 可能会返回如下数据:

{
  "id": "123",
  "author": {
    "id": "1",
    "name": "Paul"
  },
  "title": "My awesome blog post",
  "comments": [
    {
      "id": "324",
      "commenter": {
        "id": "2",
        "name": "Nicole"
      }
    }
  ]
}

我们的文章中有两个嵌套的实体:users、comments。 使用 schema,我们将数据中三个实体进行范式化:

import { normalize, schema } from 'normalizr';

// 定义用户 schema
const user = new schema.Entity('users');

// 定义评论 schema
const comment = new schema.Entity('comments', {
  commenter: user
});

// 定义文章的 schema
const article = new schema.Entity('articles', {
  author: user,
  comments: [comment]
});

const normalizedData = normalize(originalData, article);

下面是 normalizedData 的数据:

{
  result: "123",
  entities: {
    "articles": {
      "123": {
        id: "123",
        author: "1",
        title: "My awesome blog post",
        comments: [ "324" ]
      }
    },
    "users": {
      "1": { "id": "1", "name": "Paul" },
      "2": { "id": "2", "name": "Nicole" }
    },
    "comments": {
      "324": { id: "324", "commenter": "2" }
    }
  }
}

API

normalize(data, schema)

根据提供的 schema 来将数据范式化。

  • data: (required) 需要被范式化的 JSON (或者 JS 对象) 数据
  • schema: (required) 必须的模式定义

用法

import { normalize, schema } from 'normalizr';

const myData = { users: [{ id: 1 }, { id: 2 }] };
const user = new schema.Entity('users');
const mySchema = { users: [user] };
const normalizedData = normalize(myData, mySchema);

输出

{
  result: { users: [ 1, 2 ] },
  entities: {
    users: {
      '1': { id: 1 },
      '2': { id: 2 }
    }
  }
}

denormalize(input, schema, entities)

通过 schema 对 input 中指定的值进行反范式化,entities 通常是普通对象或者不可变数据(immutable)来提供。这个函数的作用是 normalize 的反操作。

特别说明:谨慎使用 denormalize,过早的将数据恢复成大型的嵌套对象,可能会对 React(和其它) 应用程序造成性能影响。

如果你的 schema 和数据具有递归应用,在会给出实体的第一个实例,后续的引用将作为提供的 id 返回。

  • input: (required) 需要被反范式化的范式化数据,通常与 normalize 输出的结果中 result 键中给出的值相同。
  • schema : (required) 用户从 input 中获取值的 schema.
  • entities: (required) 一个对象,其中可能有 schema 指定的键。还可以接受不可变数据。

用法

import { denormalize, schema } from 'normalizr';

const user = new schema.Entity('users');
const mySchema = { users: [user] };
const entities = { users: { '1': { id: 1 }, '2': { id: 2 } } };
const denormalizedData = denormalize({ users: [1, 2] }, mySchema, entities);

输出

{
  users: [{ id: 1 }, { id: 2 }];
}

schema

Array(definition, schemaAttribute)

创建一个 schema 来范式化数组。如果输入值是一个对象而不是数组,范式化结果将是对象值组成的数组。

可以使用简写方式:[mySchema]

  • definition: (required) 一单个 schema 或者模式到属性值的映射
  • schemaAttribute: (optional,如果 definition 的值不是单个 schema 时,此参数时必传) 通过指定属性来定义范式化时使用的 schema。这个参数可以接受一个字符串或者方法。这个方法有如下几个参数:
    • value: 实体的输入值
    • parent: 输入数组的父对象
    • key: 输入数组出现在复对象上的键

实例方法

  • define(definition): 使用时,传入的定义将与传递给Array构造函数的原始定义合并。这个方法在创建循环引用的时候很有用。

用法

要描述单个实体类型的简单数组:

const data = [{ id: '123', name: 'Jim' }, { id: '456', name: 'Jane' }];
const userSchema = new schema.Entity('users');

const userListSchema = new schema.Array(userSchema);
// 或者可以使用下面的简写语法
const userListSchema = [userSchema];

const normalizedData = normalize(data, userListSchema);

输出

{
  entities: {
    users: {
      '123': { id: '123', name: 'Jim' },
      '456': { id: '456', name: 'Jane' }
    }
  },
  result: [ '123', '456' ]
}

如果你的数据是包含多个实体类型的复杂数据,则必须定义 schema 映射。

如果您的数据返回了未提供映射的对象,则原始对象将在结果中返回,并且不会创建实体

For example:

const data = [{ id: 1, type: 'admin' }, { id: 2, type: 'user' }];

const userSchema = new schema.Entity('users');
const adminSchema = new schema.Entity('admins');
const myArray = new schema.Array(
  {
    admins: adminSchema,
    users: userSchema
  },
  (input, parent, key) => `${input.type}s`
);

const normalizedData = normalize(data, myArray);

输出

{
  entities: {
    admins: { '1': { id: 1, type: 'admin' } },
    users: { '2': { id: 2, type: 'user' } }
  },
  result: [
    { id: 1, schema: 'admins' },
    { id: 2, schema: 'users' }
  ]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy