Redux normalizr - 嵌套 API 响应

Redux normalizr - nested API responses

如何使用通过 { data: ... } 标准的关键响应 normalizr to deal with nested standardised JSON API

例如Book

{
    data: {
        title: 'Lord of the Rings',
        pages: 9250,
        publisher: {
            data:  {
                name: 'HarperCollins LLC',
                address: 'Big building next to the river',
                city: 'Amsterdam'
            },
        },
        author: {
            data: {
                name: 'J.R.R Tolkien',
                country: 'UK',
                age: 124,
            }
        }
    }
}   

我将如何设计架构来处理嵌套数据键?

对于响应中的每个实体,您应该创建它自己的架构。

在您的示例中,我们有三个实体 - booksauthorspublishers:

// schemas.js
import { Schema } from 'normalizr';

const bookSchema = new Schema('book');
const publisherSchema = new Schema('publisher');
const authorSchema = new Schema('author');

如果某些实体包含嵌套数据,需要规范化,我们需要使用它的define方法schema.This方法接受具有嵌套规则的对象。

如果我们需要规范化 book 实体的 publisherauthor 道具,我们应该将一个对象传递给 define 具有与我们的响应相同结构的函数:

// schemas.js
bookSchema.define({
  data: {
    publisher: publisherSchema,
    author: authorSchema
  }
});

现在我们可以规范我们的响应:

import { normalize } from 'normalizr';
import { bookSchema } from './schemas.js';

const response = {
    data: {
        title: 'Lord of the Rings',
        pages: 9250,
        publisher: {
            data:  {
                name: 'HarperCollins LLC',
                address: 'Big building next to the river',
                city: 'Amsterdam'
            },
        },
        author: {
            data: {
                name: 'J.R.R Tolkien',
                country: 'UK',
                age: 124,
            }
        }
    }
}

const data = normalize(response, bookSchema);

我相信你想要的是 assignEntity 函数的使用,它可以在 normalize 的选项中传递。在这种情况下,它允许我们在适当的情况下过滤掉多余的 data 属性并直接转到下面的值。

有效地assignEntity让您控制每个数据键的规范化方式。查看 here 了解更多有关其工作原理的信息。

我把这个放在一起作为演示,看看:http://requirebin.com/?gist=b7d89679202a202d72c7eee24f5408b6。这是一个片段:

book.define({
  data: {
    publisher: publisher,
    author: author,
    characters: normalizr.arrayOf(character)
  }}
);

publisher.define({
  data: {
    country: country
  }
});

const result = normalizr.normalize(response, book, { assignEntity: function (output, key, value, input) {
  if (key === 'data') {
    Object.keys(value).forEach(function(d){
      output[d] = value[d];
    })
  } else {
    output[key] = value;
  }
}});

另请参阅 Ln 29,其中 characters 的数组中有些对象的信息嵌套在 data 中,有些则没有。全部正确归一化。

我还添加了一些部分来展示它如何处理数组和深层嵌套数据,请参阅 publisher 中的 country 模型。

使用提供的数据,由于缺少 id,您将需要一个 slug,每个模式也包含在示例中。

Normalizr 很棒,我希望能帮助解释更多有关它的信息:)