2016-06-25 2 views
1

Предположим следующую ситуацию:Redux: Нормализация Глобальное состояние

1. Page has many posts 
2. Post has many comments 

У меня есть следующие редукторы:

1. PagesReducer 
2. PostsReducer 
3. PostReducer 
4. CommentsReducer 

У меня есть следующие состояния прямо сейчас:

pagesByTitle: { 
    dorrisPage: { 
    isFetching: false, 
    data: { 
     _id: "..." 
     title: "dorrisPage", 
    }, 
    posts: [ 
     { 
     isFetching: false, 
     data: { 
      _id: "..", 
      body: ".." 
     }, 
     comments: [..] 
     } 
    ] 
    } 
} 

выше структура выглядела нормально, но я понял, что мне нужно было передать action для дочерних состояний. Например, если я направил действие называется

ADD_COMMENT 

Я бы пройти действие вниз PagesReducer, PostsReducer, PostReducer и CommentsReducer, и, наконец, CommentsReducer будет обрабатывать это действие. Я думаю, что это когда я понял, почему нормализующие состояния рекомендуется в Redux.

Вы можете помочь мне со следующими вопросами?

  1. Является ли моя мотивация нормализации состояний правильной в этом контексте?
  2. Каков наилучший способ нормализации состояния примера?

ответ

1

вы должны избегать гнездования.

цитата из Redux документы:

В более сложном приложении, вы будете хотеть, чтобы различные объекты ссылки друг друга. Мы предлагаем сохранить ваше состояние как , нормализованное, насколько это возможно, без какого-либо гнездования. Храните каждый объект в объекте , сохраненном с идентификатором в качестве ключа, и используйте идентификаторы для ссылки на него от других объектов или списков. Подумайте о состоянии приложения как базы данных. Этот подход подробно описан в документации normalizr.

Для нормализуют состояние можно использовать normalizr

pages:{ 
    items:{ 
     1:{id: 1,title: "dorrisPage", posts:[33,57]} 
     2:{id: 2, title: "anotherPage",posts:[57]} 
    }, 
    isFetching: false, 
    itemIds:[1,2,..] 
}, 
posts:{ 
    items:{ 
     33:{id: 33,title: "Post33", comments:[1,2]} 
     57:{id: 57, title: "Post57", comments:[]} 
    }, 
    isFetching: false, 
    itemIds:[33,57,..] 
} 
comments:{ 
    items:{ 
     1:{id: 1, user: "user1", text:"fds"} 
     2:{id: 2, user: "user2", text:"fds2"} 
    }, 
    isFetching: false, 
    itemIds:[1,2,..] 
} 

"itemIds" является необходимому для элементов упорядочения

затем редукторы могут выглядеть следующим образом

export const posts = (state = initialState, action) => { 
    switch (action.type) { 

     case type.FETCH_POSTS_REQUEST: 
     case type.FETCH_POSTS_FAILURE: 
      return {...state, isFetching: action.isFetching}; 
     case type.FETCH_POSTS_SUCCESS: 
     return {...state, 
      isFetching: action.isFetching, 
      items: action.entities.posts, itemsIds: action.result 
     }; 

     case type.DELETE_POST: 
     return {...state, 
      items: omit(state.items, action.id), 
      itemsIds: state.itemsIds.filter(id=>id !== action.id) 
     }; 
     case type.UPDATE_POST: 
     return {...state, items: {...state.items, 
       [action.post.id]: {...state.items[action.post.id],...action.post}}}; 

     default: 
     return state; 
    } 
} 

гораздо проще запросить сообщение по id :

const mapStateToProps = (state,ownProps) =({ 
    post:state.posts.items[ownProps.id] 
}) 

для вычисления полученных данных из перевождь магазина, вы можете использовать Reselect для создания memoized, компонуемые селекторные функции

video tutorial

Смежные вопросы