简体   繁体   English

在两个Redux Reducers / States之间共享数据

[英]Sharing data between two Redux Reducers/States

Is this a reasonable solution for data sharing between two states/reducers? 这是两个州/减少者之间数据共享的合理解决方案吗?

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

If so, how can one guarantee the order in which reducer functions are executed if both answer to the same dispatched event and the second reducing function depends on the new state of the first one? 如果是这样,如果对同一个调度事件和第二个减少函数的回答都依赖于第一个的新状态,那么如何保证执行reducer函数的顺序呢?

Let's say that we dispatch a SET_FILTER event that appends to activeFilters collection in the filters Store and later changes the visibility of items in the events Store with respect to the activeFilters values. 假设我们调度一个SET_FILTER事件,该事件附加到过滤器Store中的activeFilters集合,然后更改事件Store中项目相对于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
    }
}

I think I found the answer - Computing Derived Data - Reselect 我想我找到了答案 - 计算派生数据 - 重新选择

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

/--------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,
}

don't forget to follow the guidelines for 'connect' 不要忘记遵循'连接'的指导方针

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

If you have two reducers, and one depend on a value from a first one, you just have to update them carefully, and the best solution will be just to use a special function, which will first set the filtering, and then query corresponding events. 如果你有两个reducers,一个依赖于第一个的值,你只需要仔细更新它们,最好的解决方案就是使用一个特殊的函数,它首先设置过滤,然后查询相应的事件。 Also, keep in mind that if events fetching is asynchronous operation, you should also nest based on filtering type -- otherwise there is a chance of race condition, and you will have wrong events. 另外,请记住,如果事件提取是异步操作,您还应该基于过滤类型进行嵌套 - 否则可能存在竞争条件,并且您将有错误的事件。

I have created a library redux-tiles to deal with verbosity of raw redux, so I will use it in this example: 我已经创建了一个库redux-tiles来处理raw redux的详细程度,所以我将在这个例子中使用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM