Redux normalize -嵌套API响应



我如何使用normalizr来处理通过{ data: ... }标准关键的嵌套标准化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,
            }
        }
    }
}   

如何设计模式来处理嵌套的数据键?

对于响应中的每个实体,应该创建它自己的模式。

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

// schemas.js
import { Schema } from 'normalizr';
const bookSchema = new Schema('book');
const publisherSchema = new Schema('publisher');
const authorSchema = new Schema('author');

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

如果我们需要规范化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让您控制如何规范化数据的每个键。请看这里了解更多关于它是如何工作的。

我把这些放在一起作为演示,看看: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,您将需要一个分隔符,在示例中每个模式也包含id。

Normalizr是非常棒的,我希望这有助于更多地解释它:)

最新更新