Нормализовать данные API для использования в Redux - PullRequest
0 голосов
/ 27 июня 2018

У меня есть следующие данные от 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 и список columns. Каждый column содержит id, name и список cards. Каждый card имеет id и name.

Я хочу нормализовать данные для использования в Redux, как представлено здесь . Я использую normalizr , чтобы сделать это следующим образом:

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)

Это приводит к следующему:

{
  "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 и allIds в соответствии с Redux ссылка на статью выше.

По сути, это упрощает упорядочивание, сортировку и т. Д. В приложении React. Я использую последнюю версию нормализатора (3.2.4).

1 Ответ

0 голосов
/ 28 июня 2018

Вот CodeSandbox с примером того, как вы можете настроить редукторы для обработки нормализованного состояния.

По сути, вы получите нечто подобное для каждой из ваших сущностей:

// 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 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 и allIds для каждой сущности при добавлении или удалении сущностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...