2016-08-31 20 views
28

Mam reduktor iw celu obliczenia nowego stanu potrzebuję danych z akcji, a także danych z części stanu, która nie jest zarządzana przez ten reduktor. W szczególności w reduktorze, który pokażę poniżej, potrzebuję dostępu do pola accountDetails.stateOfResidenceId.Jak uzyskać dostęp do stanu wewnątrz reduktora Redux?

initialState.js:

export default { 
    accountDetails: { 
     stateOfResidenceId: '', 
     accountType: '', 
     accountNumber: '', 
     product: '' 
    }, 
    forms: { 
     blueprints: [ 

     ] 
    } 
}; 

formsReducer.js:

import * as types from '../constants/actionTypes'; 
import objectAssign from 'object-assign'; 
import initialState from './initialState'; 
import formsHelper from '../utils/FormsHelper'; 
export default function formsReducer(state = initialState.forms, action) { 
    switch (action.type) { 
    case types.UPDATE_PRODUCT: { 
     //I NEED accountDetails.stateOfResidenceId HERE 
     console.log(state); 
     const formBlueprints = formsHelper.getFormsByProductId(action.product.id); 
     return objectAssign({}, state, {blueprints: formBlueprints}); 
    } 

    default: 
     return state; 
    } 
} 

index.js (reduktor główny):

import { combineReducers } from 'redux'; 
import accountDetails from './accountDetailsReducer'; 
import forms from './formsReducer'; 

const rootReducer = combineReducers({ 
    accountDetails, 
    forms 
}); 

export default rootReducer; 

Jak mogę uzyskać dostęp do tego pola?

+0

[Aktualizacja stanu w oparciu o stan aplikacji jest anty -pattern] (https://stackoverflow.com/questions/35851837/redux-and-within-a-reducer-accessing-a-different-reducer-how) – Igorsvee

+5

To stwierdzenie nie ma żadnego sensu. Cały punkt funkcji reduktora polega na tym, że podejmujesz decyzje w oparciu o * bieżący stan * i akcję. – markerikson

Odpowiedz

41

użyłbym thunk dla tego, oto przykład:

export function updateProduct(product) { 
    return (dispatch, getState) => { 
    const { accountDetails } = getState(); 

    dispatch({ 
     type: UPDATE_PRODUCT, 
     stateOfResidenceId: accountDetails.stateOfResidenceId, 
     product, 
    }); 
    }; 
} 

Zasadniczo można uzyskać wszystkie potrzebne dane na temat działań, można wysłać te dane do reduktora.

Powodzenia!

-1

Podczas wywoływania akcji można przekazać parametr. W takim przypadku można przekazać akcję accountDetails.stateOfResidenceId, a następnie przekazać ją do reduktora jako ładunek.

3

Twoje opcje polegają albo na napisaniu większej logiki oprócz samego użycia combineReducers, albo na dodaniu większej ilości danych w akcji. Redux FAQ obejmuje ten temat: http://redux.js.org/docs/faq/Reducers.html#reducers-share-state.

Ponadto obecnie pracuję nad nowym zestawem stron do dokumentów Redux na temat "Structuring Reducers", które mogą okazać się pomocne. Aktualne strony WIP są na https://github.com/markerikson/redux/blob/structuring-reducers-page/docs/recipes/StructuringReducers.md.

+0

Dzięki za odpowiedź. Zbadałem niektóre z zasobów, które łączyłeś i nadal będziesz to robić. Jednak pytanie dla ciebie, ponieważ wydajesz się być kompetentny. Inna odpowiedź sugeruje użycie 'thunk'. Czy uważasz, że byłoby to dobre rozwiązanie mojego problemu? Jeśli to zrobi bałagan z mojego kodu lub nie jest najlepszą praktyką, nie jest to rozwiązanie, które chcę realizować, ale nie czuję się wystarczająco kompetentny, aby określić długoterminowe skutki tych wyborów. – Tylerlee12

+1

Yup, thunks to standardowe podstawowe podejście do zarządzania efektami ubocznymi i wykonywania złożonej logiki, która obejmuje wiele wywołań i korzystanie z bieżącego stanu aplikacji. Jest całkowicie normalne, aby napisać funkcję thunk, która odczytuje bieżący stan aplikacji, i robi rzeczy takie jak wysyłanie warunkowo, wysyłanie wielu akcji, lub chwyta część stanu i włącza to w wywoływanej akcji. Mam kilka przykładów wspólnych wzorców thunk na https://gist.github.com/markerikson/ea4d0a6ce56ee479fe8b356e099f857e. – markerikson

0

Sugeruję, aby przekazać go twórcy akcji. Więc gdzieś będziesz miał twórca działania, który robi coś takiego:

updateProduct(arg1, arg2, stateOfResidenceId) { 
    return { 
    type: UPDATE_PRODUCT, 
    stateOfResidenceId 
    } 
} 

W miejscu, gdzie można wywołać działanie załóżmy używasz reagować, można użyć

function mapStateToProps(state, ownProps) { 
    return { 
    stateOfResidenceId: state.accountdetails.stateOfResidenceId 
    } 
} 

i połączyć do komponentu reagującego za pomocą połączenia react-redux.

connect(mapStateToProps)(YourReactComponent); 

Teraz, w swojej reagować składnik, gdzie można wyzwolić updateProduct działania, należy mieć stateOfResidenceId jako rekwizyt, można przekazać je do swojego twórcy akcji.

Brzmi zawiło, ale tak naprawdę chodzi o rozdzielenie obaw.

0

Można spróbować użyć:

redux-named-reducers

który pozwala uzyskać stan nigdzie w kodzie tak:

const localState1 = getState(reducerA.state1) 
const localState2 = getState(reducerB.state2) 
Powiązane problemy