Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux - Is there any way to access store tree in reducer?

Tags:

redux

In my case, I have a store like:

{
  aa: {...},
  bb: cc  // the result of computing with aa
}

I need to update aa and bb at the same time, but bb need to get the latest computation of aa.

Here is some code(React.js):

onClick(e) {
  const { dispatch, aa, bb } = this.props;

  dispatch(updateAa());
  dispatch(updateBb(aa)); // can not get the latest computation of aa, it is the last computation..
}

So, is this mean that I need to get aa in bb's reducer?

And How can I do it?

Hope for helps!, Thanks!

like image 213
user2331095 Avatar asked Dec 22 '15 16:12

user2331095


People also ask

How do I access data from Redux store?

It's simple to get access to the store inside a React component – no need to pass the store as a prop or import it, just use the connect function from React Redux, and supply a mapStateToProps function that pulls out the data you need. Then, inside the component, you can pass that data to a function that needs it.

Where is Redux store saved?

It's stored in browser's memory.

How do you share States between reducers?

How do I share state between two reducers? Do I have to use combineReducers ? ​ The suggested structure for a Redux store is to split the state object into multiple “slices” or “domains” by key, and provide a separate reducer function to manage each individual data slice.

Should I keep all component's state in Redux store?

Yes, it's worth striving to store all component state in Redux. If you do, you will benefit from many features of Redux like time travel debugging and replayable bug reports. If you don't, those features could be completely unusable.


2 Answers

don't use combineReducers.

Example

replace this code

export const a = combineReducers({
  app,
  posts,
  intl,
  products,
  pos,
  cats,
});

with

export default (state = {}, action) => {
  return {
    app: app(state.app, action, state),
    posts: posts(state.posts, action, state),
    intl: intl(state.intl, action, state),
    products: products(state.products, action, state),
    pos: pos(state.pos, action, state),
    cats: cats(state.cats, action, state),
  };
};

reducer would be like

const reducer = (state = initialState, action, root) => {....}
like image 156
Sheikh Abdul Wahid Avatar answered Oct 03 '22 14:10

Sheikh Abdul Wahid


There are several possibilities, but it's tough to say which is best, given the vagueness of the code.

  • Ideally, your store should be normalized, meaning that each piece of data is only available in one place. Then you would calculate derived data after reading the store, such as when you use the selector pattern described in the guide to map the state of the store to what you might consider a materialized view that will be sent to your components as props. In this workflow, aa and bb would each be produced by selector functions, rather than stored in that store itself.
  • You could leave the reducer that updates aa and bb outside of combineReducers, so that it sees the whole state, rather than the state scoped down to aa and bb.
  • You could factor out your calculation code into a helper that could be called by updateAa and updateBb, and pass enough info in each action to make the calculation.
  • You could calculate the update before dispatching, so that the action contains the right value.
like image 27
acjay Avatar answered Oct 03 '22 14:10

acjay