Javascript 规范化API数据以在Redux中使用

Javascript 规范化API数据以在Redux中使用,javascript,reactjs,redux,normalizr,Javascript,Reactjs,Redux,Normalizr,我有来自API的以下数据: const data = { id: 1, name: 'myboard', columns: [ { id: 1, name: 'col1', cards: [ { id: 1, name: 'card1' }, { id: 2, name: 'card2' } ] }, { id: 2, name: 'col2',

我有来自API的以下数据:

const data = {
  id: 1,
  name: 'myboard',
  columns: [
    {
      id: 1,
      name: 'col1',
      cards: [
        { id: 1, name: 'card1' },
        { id: 2, name: 'card2' }
      ]
    },
    {
      id: 2,
      name: 'col2',
      cards: [
        { id: 3, name: 'card3' },
        { id: 4, name: 'card4' }
      ]
    },
  ]
}
如您所见,基本上有3个嵌套级别。顶层包含一个
id
name
和一个
列列表。每个
包含一个
id
名称
和一个
卡片列表
。每个
都有一个
id
名称

我希望将数据规范化,以便在Redux中使用。我使用的方法如下:

const card = new schema.Entity('cards');
const column = new schema.Entity('columns', {
  cards: [card]
});
const board = new schema.Entity('boards', {
  columns: [column]
});

normalize(data, board)
const addData = ({ entities }) => ({
  type: 'ADD_DATA',
  payload: entities // note the rename - this is not required, just my preference
})

// I used a thunk, but theory is the the same for your async middleware of choice
export const getData = () => dispatch => dispatch(addData(normalize(data, board)))
其结果如下:

{
  "entities": {
    "cards": {
      "1": {
        "id": 1,
        "name": "card1"
      },
      "2": {
        "id": 2,
        "name": "card2"
      },
      "3": {
        "id": 3,
        "name": "card3"
      },
      "4": {
        "id": 4,
        "name": "card4"
      }
    },
    "columns": {
      "1": {
        "id": 1,
        "name": "col1",
        "cards": [1, 2]
      },
      "2": {
        "id": 2,
        "name": "col2",
        "cards": [3, 4]
      }
    },
    "boards": {
      "1": {
        "id": 1,
        "name": "myboard",
        "columns": [1, 2]
      }
    }
  },
  "result": 1
}
我似乎不知道如何将每个部分(即:
cards
columns
boards
)分成两个部分,即
byId
allid
,如上文提到的Redux文章所述

本质上,这是为了使React应用程序中的排序、排序等更容易。我正在使用最新版本的normalizer(3.2.4)。

介绍如何设置减速器以处理规范化状态

基本上,对于每个实体,您都会得到这样的结果:

// lambda or function - whatever your preference is
const cardsById = (state = {}, action) => {
  // if, case, handler function - whatever your preference is
  if (action.type === 'ADD_DATA') { // or whatever your initial data load type is
    return { ...state, ...action.payload.cards }
  }
  return state
}

const allCards = (state = [], action) => {
  if (action.type === 'ADD_DATA') { // or whatever your initial data load type is
    return [...state, ...Object.keys(action.payload.cards)]
  }
  return state
}

const cards = combineReducers({
  byId: cardsById,
  allIds: allCards
})
然后将所有这些结合在一起:

export default combineReducers({
  cards,
  columns,
  boards
})
此操作的操作创建者如下所示:

const card = new schema.Entity('cards');
const column = new schema.Entity('columns', {
  cards: [card]
});
const board = new schema.Entity('boards', {
  columns: [column]
});

normalize(data, board)
const addData = ({ entities }) => ({
  type: 'ADD_DATA',
  payload: entities // note the rename - this is not required, just my preference
})

// I used a thunk, but theory is the the same for your async middleware of choice
export const getData = () => dispatch => dispatch(addData(normalize(data, board)))

希望这有帮助。请记住,在添加或删除实体时,您将需要为每个实体维护
byId
allid

文档的部分将进入该部分。基本上,您需要自己管理它们。下一页将详细介绍如何更新已采用正确格式的存储。这一切都有道理。然而,我仍然不确定如何首先创建初始的规范化结构。根据我文章中的示例,初始数据来自API,然后我需要对其进行规范化,并为每个部分包括
byId
allid
。这是我不确定的部分。如果明天我有时间,我会给你举个例子作为答案。现在一切都有意义了。谢谢,比如说谢谢。但是如何在redux存储中实现交叉表呢?比如说,如果我有cards和card_members表,如何实现它们之间的关系?因为规范化状态形状redux文档表示,每种类型的数据在状态中都有自己的“表”。