2016-01-29 20 views
5

比方說,我有這樣的結構,這是一個結果從一個API,並獲取使用我的實體「normalizr」:React redux normalizr:如何處理嵌套實體?

entities: { 
    users:{ 
     1: { 
      name: 'John', 
      posts: [ 1, 4 ] 
     } 
    }, 
    posts: { 
     1: { 
      name: 'First Post', 
     }, 
     4: { 
      name: 'Second Post', 
     } 
    } 
} 

現在我有一個過濾用戶的帖子,一種方法,其會做基本上是這樣的:

let filteredPosts = {}; 
entities.users.posts.forEach(key => { 
    if(posts.hasOwnProperty(key)) 
     filteredPosts[key] = posts[key] 
}); 

這顯示了該用戶的帖子,例如頁:

render() { 
    return(
     <div> 
      {Object.keys(filteredPosts).map(key => { 
       return (
        <div>{filteredPosts[key].name}</div> 
       ); 
      })} 
     </div> 
    ) 
} 

我的實體減速機版本Ÿ簡單:

import { merge } from 'lodash'; 
... 
function entities(state = { users: {}, posts: {} }, action) { 
    if (action.response && action.response.entities) { 
     return merge({}, state, action.response.entities); 
    } 
    return state; 
} 

現在,如果我做的API請求添加後該用戶,返回新創建的職位的記錄,該記錄將被自動添加到職位上我的實體。

我怎麼會處理更新用戶反映這種變化,使用戶現在有3個職位,新職位ID陣列中?

我應該創建一個減速器和聽後創建行動,並更新在那裏state.entities.users.posts?重新獲取實體似乎不是一種選擇。最好的辦法是什麼?

感謝

UPDATE:

這是我在用,現在來保持數據一致的解決方案。我修改了我對創建的帖子ID的回覆。我知道這可以分解爲多個reducer,但我仍然想知道是否有更好更直接的方法,我不必爲每個嵌套實體都這樣做。

function entities(state = {}, action) { 
    ... 

    if(action.type === 'POST_ADD_SUCCESS') { 
     // Get the user id from the created post 
     let userId = response.entities.posts[response.result].userId; 
     // Add the user with all his posts to the response 
     response.entities.users = { 
      [userId]: { 
       posts: [...state.users[userId].posts, response.result] 
      } 
     } 
    } 
    ... 
    // Merge normally 
    return merge({}, state, response.entities); 
} 

回答

1

你更新的片段看起來大多是沿着正確的道路,雖然我不知道爲什麼你仍然在那裏引用「響應」。你的動作製作功能或許應該被抓住了用戶ID和帖子ID,當AJAX調用成功,創建一個看起來像{type : POST_ADD_SUCCESS, userId : userId : postId}動作。換句話說,減速器根本不應該知道任何關於「響應」的事情,只是應該在用戶ID「y」的列表中添加帖子ID「x」。

+0

這就是我的意思,當我說,它可以被分解成多個減速,而且比在這種情況下,我只想引用陳述自己而不是迴應。 關於如何使這個自動的任何建議?如果做到這一點,我將不得不編寫一堆嵌套減速器,因爲我正在使用減速器工廠,就像現實世界中的redux示例一樣,它感覺就像是失敗了。 另一個想法我是爲了擺脫後陣列上的用戶的,而是具有非嵌套postsByUserId減速。這似乎是大多數人做的事情,我只是不知道該怎麼做。 –

0

東西你有沒有考慮派遣與格式化實體上成功發佈新動作的API?

const foo = (entities) => { 
    type: "POST_ADD_SUCCESS" 
    response : { entities } 
} 

動作類型並不重要,你的實體減速機將攔截行動反正