angularjsreduxreusabilityplugin-architecturecomponent-based

How to structure Redux for a highly de-coupled, plug-n-play complex component?


I'm pretty new to Redux and would like to use it my application but I'm stuck at architecture/design phase for the Redux part. Here are my requirements and my suppositions regarding the design.

Application details: SPA with AngularJS. Other libs used ng-redux, reselect, rxjs.

Component details: Re-usable grid component to render huge amounts of data.

My idea: Create a plug-n-play kind of component-based architecture, where all the internal components of the grid are independent of the parent/composing component like search, sort, row, header, cell.

  1. All the components will have their own set of reducer, action, selector, and slice of state from the store.

  2. Because all the components have their own reducers and can be plugged-in on demand, I need them to be lazily registered to the store instead of being accumulated in one place.

  3. Some of the components like search, sort along with having their own state, also can affect other components state. Ex: setting up of query parameters (searchText, sortOrder etc.) to fetch the grid data which would be handled by another component(s).

My thoughts:

  1. For the 1st point, I'm looking into reselect for supplying the dependent slice of state.

  2. For the 2nd point, I'm still confused about which to use combineReducers/replaceReducer for the lazy registration. I feel combineReducers will not fit if I want access to multiple parts of the state.

  3. For the 3rd point, I'm thinking of following approaches:

    a. Passing entire state via getState() wherever required to update multiple parts of the state. Though this approach gives me feeling of improper use of Redux.

    b. Component A fires its own action which updates their part of the state, then another action is fired for the other component B to update its slice of state. This approach as well feels like breaking the whole idea of Redux, the concept of side-effect could be used here though I don't know how to use it, maybe redux-saga, redux-thunk etc.

NOTE: Use of either of the approaches shouldn't lead to the component knowing about the other components hence whatever has to be done will be done by passing a generic config object like { actionsToFire: ['UPDATE_B'] }.

  1. I need state management while navigating back and forth between the pages of the application, but I don't require hot-reloading, action-replay, or pre-fetching application state from server-side.

  2. Components will also be responsible to destroy their state when no longer required. And state will have a normalized structure.

I know the requirements might seem weird or not-seen-often but I would keep them that way.

Few things I already know are:

  1. I don't need to use Redux like the classic article from Dan says, but I think I need it here in this case.

  2. I know about the Smart and Dumb components, mostly my components might seem smart (i.e aware of application state) but that is how I want to keep them, I might be wrong.

Diagram of the grid component:

Grid Component Diagram


Solution

  • Redux's global store makes encapsulation and dynamic plug-and-play behavior more difficult, but it is possible. There's actually many existing libraries for per-component-instance state and dynamic registration of reducers. (That said, the libraries I've seen thus far for component management are React libraries - you'd have to study some of those and reimplement things yourself for use with Angular.)