2017-03-02 9 views
0

현재 Redux로 시작하고 있으며, 감속기를 동적으로 서브 상태에 연결하는 올바른 방법은 무엇인지 명확하지 않습니다.상태의 서브 세트에 리듀서를 동적으로 설정합니다.

예를 들어의 내 상태 (비동기 백엔드 API를 일부 데이터를 가져 오는 후) 다음과 같습니다 가정 해 봅시다

{ 
    "categories": { 
     "collection": { 
     "42": { 
      "id": "42", 
      "title": "whatever", 
      "owner_id": "10" 
      "posts": { 
       "collection": { 
       "36": { 
        "id": "36", 
        "title": "hello", 
        "content": "hello world" 
       }, 
       "37": { // more posts ... } 
       }, 
       "ids": ["36", "37", ...] 
      }, 
      "otherChildren": { // more sub-entities } 
     }, 
     "43": { // more categories ... } 
     }, 
     "ids": ["42", "43", ...] 
    }, 
    "users": { 
    "collection": { 
     "10": { 
      "id": "10" 
      "email": "[email protected]" 
     }, 
     "11": { // more users ... } 
    }, 
    "ids": [10, 11] 
    } 
} 

과 같을 것이다 나의 루트 감속기 :

export default combineReducers({ 
    categories: categoriesReducer, 
    users: usersReducer 
}) 

과 categoriesReducer :

function categoriesReducer(state = initialState, action) { 
    switch (action.type) { 
    case FETCH_ALL_CATEGORIES_SUCCESS: 
     return Object.assign({}, state, { 
     categories: { 
      collection: action.payload 
     } 
     }) 
    default: 
     return state 
    } 
} 

이제 내가하고 싶은 것은 원활하게 핸들을 위임하는 것입니다. postsReducer 기능 상태의 post 부분 집합의 부분은 기본적으로 같은 케이스를 추가 : 물론

case FETCH_CATEGORY_ALL_POSTS_SUCCESS: 
    let categoryId = action.categoryId 
    return Object.assign({}, state, { 
     categories: { 
     [categoryId]: combineReducers({ 
      "posts": postsReducer, 
      "otherChildren": otherChildrenReducer 
     }) 
     } 
    } 

이 작동하지 않습니다. 내가 얻지 못하는 것은 중첩 된 감속기에 대해 combineReducer를 사용하여 상태의 하위 집합을 자동으로 업데이트하는 redux를 얻는 방법입니다. 자동으로 적절한 인수를 감속기 함수에 상태 인수로 전달하고 기존 데이터를 재정의하지 않습니다 (예 : 내보기).

나는 그 일을 내 자신의 "위임자"권한으로 작성했지만 그게 꽤 틀렸다고 느꼈다. 정확히 말하면 https://github.com/reactjs/redux/blob/master/src/combineReducers.js을 보았다.

저는 어떻게 전통적으로 그렇게할까요? 그 방법으로 combineReducers를 Redux와 같은 방법으로 사용하는 것이 가능합니까? 제가 CombinedReducer의 요점을 오해하고 있습니까? 아니면 그로부터 많은 마법을 기대합니까?

감사합니다.

EDIT/UPDATE :

나는, 즉 여기 (postsReducer (오른쪽, 어쩌면 category/post 예는 오른쪽에 하나가 아닌) 내가 감속기를 원하는 사람들은 중첩 될 필요가 정말로 그러나 여러 곳에서 재사용 할 수있는 Collection 감속기가 될 수 있습니다.

(이유는 그것이 중첩 될 하시겠습니까? 사실 그 예에서의이 post의 데이터가 실제로 category에서 개인 키를 사용하여 암호화되어 있기 때문에 하나 post 만, 하나 category에 속할 수 있다고 가정 해 봅시다. 이유를 그

국가의 적절한 부분 집합을 전달하는 동안 다른 감속기에 위임하는 방법은 없습니다. 즉, 통과하는 것입니다. postReducer에 categories.collection.42.posts.collection.36 상태?

+0

"자동 업데이트"는 없습니다. 리 듀서는 ** 기능 **입니다. 아이디어를 얻으려면 http://redux.js.org/docs/recipes/StructuringReducers.html을 읽어보십시오. – markerikson

+0

다른 데이터 엔티티에 대해 비슷하거나 똑같은 감속기를 원할 경우 감속기 생성기 작성 : http://redux.js.org/docs/recipes/ReducingBoilerplate.html#generating-reducers (http : : //redux.js.org/docs/recipes/reducers/ReusingReducerLogic.html. 위임을 할 수는 있지만 단 하나의 방향으로 만 수행 할 수 있습니다. 최종 결과는 감속기 트리입니다. 하지만 당신이 말하는 것은 순환 위임 같은 것입니다. – NateQ

+0

저장소의 한 유형의 데이터 엔티티를 실제로 다른 저장소 내에 중첩 시키려면 트리 구조로 축소 기 (reducers)를 구현하는 한 자유롭게 할 수 있습니다. 위의 markerikson이 제안한대로, 나는 또한 당신이 http://redux.js.org에있는 문서를 읽고 매우 잘 쓰여지고 도움이된다고 제안한다. 감사합니다 @ Borjante. – NateQ

답변

0

어디에서나 가게와 잘 어울리는 이유는 무엇입니까?

는 말은 귀하의 게시물해야/다른 감속기를 가질 수, 가게 것 엔까지이 같은 :

{ 
    categories: [], 
    posts: [], 
    users: [] 
} 

귀하의 범주는 다음 게시물 만 ID 년대 포함됩니다

그래서 당신은 할 수 있었다 "캡처 카테고리와 새로운 게시물 감속기 모두에서 "FETCH_ALL_CATEGORIES_SUCCESS"작업, categoryReducer에서 카테고리 데이터 및 ID의 안전성을 확인하고 postsReducer는 게시물을 저장합니다.

+0

. 나는 몇 가지 세부 사항으로 질문을 업데이트한다. thanks @ NateQ. – nakwa

0

잘못된 방식으로 combineReducers를 사용하고 있습니다.마지막 코드 조각. (categoryReducer와 usersReducer를 함께 사용하는 첫 번째 스 니펫에서는 정확합니다.)

FETCH_CATEGORY_ALL_POSTS_SUCCESS의 경우에는 combineReducers를 호출하는 대신 categoriesReducer 내부에서 일반 함수를 호출하면됩니다.

posts: posts(action.payload.posts) 

이 일반 기능은 기본적으로 하위 축소 기입니다. 당신이 직접 쓰는 것이고 아마도 같은 파일에 넣을 것입니다. 위의 코드

그러나 다른 두 주요 이슈 :

1) 다른 사용자로 이미 아마 범주의 하위 속성으로 게시물을 저장하는 가장 좋은되지 않을 것, 위 말했다. 게시물을 상태 트리 내에서 자신의 항목으로 저장하고 각 게시물에 속한 category_id 필드 만 있으면 속한 카테고리를 표시 할 수 있습니다. 그래서 경우에 당신의 국가 트리과 같습니다

{ 
    categories: {}, 
    posts: {}, 
    users: {} 
} 

과 같이 처음 combineReducers을 사용합니다 :) 그 문제에 대한 모든을 categoriesReducer 내)

export default combineReducers({ 
    categories: categoriesReducer, 
    posts: postsReducer, 
    users: usersReducer 
}) 

2 (또는, 당신은하지 않습니다 을 호출 할 때 이미 해당 속성을 만들었으므로 categories 속성이 있어야합니다. 다른 말로하면 categoriesReducer에서이 값을 가져야합니다.

function categoriesReducer(state = initialState, action) { 
    switch (action.type) { 
    case FETCH_ALL_CATEGORIES_SUCCESS: 
     return Object.assign({}, state, { 
     collection: action.payload, 
     ids: // function to extract ids goes here 
     }); 
    default: 
     return state; 
    } 
} 
+0

나는 몇 가지 세부 사항으로 질문을 업데이트한다. – nakwa