2016-01-10 8 views
7

Czy jest to rozsądne rozwiązanie do udostępniania danych między dwoma stanami/reduktorami?Udostępnianie danych między dwoma Redux Reduktorami/państwami

//combineReducers 
function coreReducer(state = {}, action){ 

    let filtersState = filters(state.filters, action); 
    let eventsState = events(state.events, action, { filters: filtersState}); 

    return { events: eventsState, filters : filtersState}; 

} 

export const rootReducer = combineReducers(
    { 
     core : coreReducer, 
     users 
    } 
); 

Jeśli tak, to w jaki sposób można zagwarantować kolejności, w jakiej są wykonywane funkcje reduktor jeśli zarówno odpowiedź do tej samej wysłane zdarzenia i drugiej funkcji redukującej zależy od nowego stanu pierwszego?

Załóżmy, że wysyłamy zdarzenie SET_FILTER, które dołącza do kolekcji activeFilters w magazynie filtrów, a następnie zmienia widoczność elementów w magazynie zdarzeń pod kątem wartości activeFilters.

//ActiveFilters reducer 
function filtersActions(state = {}, action){ 

    switch (action.type) { 
     case SET_FILTER: 
      return Object.assign({}, state, { 
       [action.filterType]: action.filter 
      }) 
     case REMOVE_FILTER: 
      var temp = Object.assign({}, state); 
      delete temp[action.filterType]; 
      return temp; 

     case REMOVE_ALL_FILTERS: 
      return {}; 

     default: 
      return state 
    } 
} 

Myślę, że znalazłem odpowiedź - Komputery opracowanych danych - Wybierz ponownie

http://redux.js.org/docs/recipes/ComputingDerivedData.html

+1

To wydaje mniej niż idealne. Redukcje powinny być funkcją państwa i działania, nic więcej. Przekazanie trzeciego argumentu do reduktora zdarzeń jest jednoznaczne. Pomogłoby to dowiedzieć się więcej o tym, co się tutaj dzieje. Jak wyglądają reduktory "filters" i "events"? –

+0

Cześć! Czy dzieliłeś stan między reduktorami za pomocą reselekcji? Jak to zrobiłeś? –

+0

Znaleźliśmy inne rozwiązanie z opcją 'mapStateToProps' – Gorilla

Odpowiedz

0
/--------container--------/ 
import {getGroupsAndMembers} from '../reducers' 
const mapStateToProps = (state) => { 
    return { 
    inputValue: state.router.location.pathname.substring(1), 
    initialState: getGroupsAndMembers(state) <-- this one 
} 
} 


/--------reducers--------/ 
export function getGroupsAndMembers(state){ 
    let { groups, members } = JSON.parse(state) 
    response = {groups, members} 
    return response; 
} 


GroupsContainer.propTypes = { 
//React Redux injection 
pushState: PropTypes.func.isRequired, 
// Injected by React Router 
children: PropTypes.node, 
initialState:PropTypes.object, 
} 

nie zapomnij, aby postępować zgodnie z wytycznymi dla 'connect'

export default connect(mapStateToProps,{ pushState })(GroupsContainer) 
0

Jeśli masz dwa reduktory i jeden zależy od wartości z pierwszego, po prostu musisz zaktualizować je ostrożnie, a najlepszym rozwiązaniem będzie użycie specjalnej funkcji, która najpierw ustawi filtrowanie, a następnie odpytuje odpowiednie zdarzenia. Pamiętaj też, że jeśli pobieranie zdarzeń jest operacją asynchroniczną, powinieneś również zagnieżdżać w oparciu o typ filtrowania - w przeciwnym razie istnieje szansa na wyścig, a będziesz miał złe zdarzenia.

I have created a library redux-tiles do czynienia z gadatliwości surowego Redux, więc będę używać go w tym przykładzie:

import { createSyncTile, createTile } from 'redux-tiles'; 

const filtering = createSyncTile({ 
    type: ['ui', 'filtering'], 
    fn: ({ params }) => params.type, 
}); 

const events = createTile({ 
    type: ['api', 'events'], 
    fn: ({ api, params }) => api.get('/events', { type: params.type }), 
    nesting: ({ type }) => [type], 
}); 

// this function will just fetch events, but we will connect to apiEvents 
// and filter by type 
const fetchEvents = createTile({ 
    type: ['api', 'fetchEvents'], 
    fn: ({ selectors, getState, dispatch, actions }) => { 
    const type = selectors.ui.filtering(getState()); 
    return dispatch(actions.api.events({ type })); 
    }, 
}); 
Powiązane problemy