2016-08-09 170 views
7

Also arbeite ich an einer großen react/redux app und bin sehr glücklich darüber, wie einfach es ist, redux zu verwalten. Wir verwenden einen "Enten" -Stil-Ansatz für Reducer/Action/Action Creators, um die Dinge relativ domänenbasiert zu halten. Darüber hinaus versuchen wir, den Status ui mit der Domain zu verknüpfen, und die meisten Reducer haben eine ähnliche Struktur. Es sieht etwa so aus:Wiederverwendung von Aktionen über mehrere Reducer in redux

export default function home(state = initialState, action = {}) { 
    switch (action.type) { 
    case OPEN: 
     return { 
     ...state, 
     ui: { 
      ...state.ui, 
      [action.key]: true 
     } 
     }; 
    case CLOSE: 
     return { 
     ...state, 
     ui: { 
      ...state.ui, 
      [action.key]: false 
     } 
     }; 
    case SELECT_TAB: 
     return { 
     ...state, 
     ui: { 
      selectedTab: action.selected 
     } 
     }; 
    default: 
     return state; 
    } 
} 

wir die gleichen Aktionen über wiederholte am Ende mit und über die ui, hauptsächlich schaltet und Einstellung, was angezeigt wird. Gibt es eine Möglichkeit, die Domain-basierte UI in einem Reducer zu halten, ohne die OPEN und CLOSE Anweisungen für die Ui in jedem Reducer hinzufügen zu müssen. Vielleicht denke ich an ein Anti-Pattern in Redux, aber neugierig, ob jemand schon einmal auf diese Art von Problem gestoßen ist?

UPDATE:

Ich mag die Lösung unten aufgeführt, aber wie würden Sie die Minderer erweitern, um eine Art von ui Minderer in ihm enthalten.

Auf diese Weise können Sie Domain-basierte UI geschachtelt haben, ohne alle Aktionen zu wiederholen. Sie sind sich nicht sicher, wie Sie das machen würden, weil Sie CASE-Anweisungen im Wesentlichen dynamisch hinzufügen würden.

Antwort

6

Nun, Sie müssten sie mit einem Präfix Namespace. Wenn Sie sind, wie die meisten Entwickler sind, faul, dann eine Hilfsfunktion erstellen, die die Reduzierungen für Sie erzeugen würde;)

Wie dieses ..

const createOpenCloseReducer = (prefix, initialState) => { 
    const = ui = prefix + "_UI"; 

    return (state = initialState, action) => { 
    switch(action.type) { 
    case (prefix + "_CLOSE"): 
     return { ...state, [ui]: "CLOSED" } 
    case (prefix + "_OPEN"): 
     return { ...state, [ui]: "OPENED" } 
    default: 
     return state 
    } 
    } 
} 

import { combineReducers, createStore } from 'redux'; 

const rootReducer = combineReducers({ 
    home: combineReducers({ 
     ui: createOpenCloseReducer("HOME", { "HOME_UI": "CLOSED" }), 
     data: someOtherHomeDataReducer 
    }), 
    someOther: createOpenCloseReducer("OTHER", { "OTHER_UI": "CLOSED" }) 
}) 

store = createStore(rootReducer) 

// use it.. 
store.dispatch({type: "HOME_CLOSE"}) 
store.dispatch({type: "OTHER_OPEN"}) 

// your state.. 
store.getState().home.ui // {HOME_UI: "CLOSED"} 
store.getState().someOther // {OTHER_UI: "OPENED"} 
+0

Danke für die Antwort, aber ich habe schon Jede Aktion Namespaced wie 'const OPEN = 'if-Planung/home/OPEN';' Ich denke, was ich nicht ganz bekomme, ist, selbst wenn ich eine Hilfsfunktion hatte, die eine Reihe von Standard-ui-Aktionen hatte. Wo würde ich es in das Original Reducer legen? –

+0

@PhilipChmalts checken Sie die Bearbeitungen .. so würde ich es verwenden .. – webdeb

+0

So nah, aber nicht genau das Problem der anderen Aktionen in der Heimat Reducer überprüfen Sie meine Bearbeitung bei dem, was ich versuche zu erreichen . –