2016-08-09 8 views
7

Pracuję więc nad dużą aplikacją reagującą/redux i byłem bardzo zadowolony z tego, jak łatwo jest zarządzać stanem w reduxie. Używamy podejścia typu "kaczki" do twórców reduktorów/akcji/akcji, aby utrzymać relacje oparte na domenie. Ponadto staramy się zachować stan ui związany z domeną, a większość reduktorów ma podobną strukturę. Wygląda to mniej więcej tak:Ponowne użycie działań w wielu reduktorach w reduxie

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; 
    } 
} 

skończymy mając te same czynności powtarzających się w kółko za UI, głównie przełączanie i ustawienie co jest wyświetlane. Czy istnieje sposób na utrzymanie interfejsu użytkownika opartego na domenie w reduktorze bez konieczności dodawania instrukcji typu for w każdym redugerze. Może to, o czym myślę, to anty-wzorzec w reduxie, ale ciekawy, czy ktoś już wcześniej miał taki problem?

UPDATE:

Lubię rozwiązania wymienione poniżej, ale w jaki sposób przedłużyć reduktor do sortowania zawierać reduktor ui jego obrębie.

combineReducers({ 
    home: {createUiReducer('home', initialState), ...home} 
}) 

W ten sposób można zagnieżdżać ui oparte na domenie bez powtarzania wszystkich czynności. Nie jestem pewny, jak byś to zrobił, ponieważ zasadniczo dynamicznie dodawałbyś instrukcje CASE.

Odpowiedz

6

Cóż, potrzebujesz przestrzeni nazw z prefiksem. Jeśli są, podobnie jak większość deweloperów są leniwi, a następnie utworzyć funkcję pomocnika, który będzie generować reduktorów dla Ciebie;)

jak ten jeden ..

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

Dzięki za odpowiedź, ale już mam każda akcja o nazwie tak jak 'const OPEN = 'if-planning/home/OPEN';' Domyślam się, że nie całkiem dostaję, nawet jeśli miałem funkcję pomocnika, która miała zestaw domyślnych akcji ui. Gdzie umieściłbym go wewnątrz oryginalnego reduktora? –

+0

@PhilipChmalts sprawdź zmiany ... tak bym to użył .. – webdeb

+0

Tak blisko, ale nie rozwiązuje dokładnie problemu posiadania innych akcji w reduktorze domu sprawdź moją edycję, co próbuję osiągnąć . –