问题
Say I have two reducers.
Reducer No.1 : Currently-Selected-Item-Reducer
state = {currentlySelectedItemId: 123}
Reducer No.2 : All-Items-Reducer
state = [{ id: 123, name: "John"}, {id: 231, name: "Jill"}, {id: 411, name: "Alf"}]
I have a simple React app and a React component simply displays the currently selected item. I.e., based on the id in the currently-selected-item-reducer
, it find the correct item to display in the all-items reducer
.
Problem:
Say the currently selected item is 123
and I want to go to implement a button which will always go the next item in the array. Now I need to find item 123
in the all-items-reducer
, get its index in that array, and then increment it. Then my React component will do the rest.
However, this means that I need to access the array of the all-items-reducer
in my current-item reducer
. How is this possible? Or am I misunderstanding something here?
PS: I would prefer to not introduce a counter in my currently-selected-item-reducer
, since this would be redundant information: I should, in theory, be able to find the item position of the current selection by looking at the all-items-reducer array
and do a findIndex()
or something like that.
回答1:
There are a few approaches you can take:
- Combine the two reducers; one could argue that the two segments of state are so interrelated that one reducer should take care of everything.
- Duplicate some data across reducers (obviously is wasteful, but if the reducers are truly very separate, a little redundancy might be warranted)
- Let your component layer figure out what the next item is and dispatch the specific ID to select.
- Use something like the
redux-thunk
middleware which lets you not-only dispatch a multi-action-creating action but also lets you query state.
Sample of redux-thunk
approach:
function gotoNextItem() {
return (dispatch, getState) => {
const { current, items } = getState(); // or whatever the reducers are called
const index = items.findIndex(item => item.id === current.currentlySelectedItemId);
const newIndex = (index + 1) % items.length;
const newItem = items[newIndex];
dispatch({ type: 'SELECT_ITEM', payload: { item: newItem } });
};
}
store.dispatch(gotoNextItem());
来源:https://stackoverflow.com/questions/51642726/redux-reducer-needs-state-of-other-reducer