microsoft / redux-dynamic-modules

Modularize Redux by dynamically loading reducers and middlewares.
https://redux-dynamic-modules.js.org
MIT License
1.07k stars 116 forks source link

Module dependencies result in duplicated data in store #140

Closed dkreft closed 4 years ago

dkreft commented 4 years ago

I have a module that depends upon several other modules that are scoped to the primary module, but when I load the page, I'm seeing the dependant modules as both peers of my primary module and as children of it.

Primary module

/* File: CustomerDetailsPage/store/module.js */

// Peers
import { getModule as getBillingAccountModule } from 'store/billingAccount'
import { getModule as getAssignableUsersModule } from 'store/assignableUsers'

// Children
import { getModule as getCustomerModule } from './customer'
import { getModule as getOrdersModule } from './orders'
import { getModule as getEnrollmentRecordsModule } from './enrollmentRecords'
import { getModule as getPaymentObligationsModule } from './paymentObligations'

export function getModule() {
  return [
    getAssignableUsersModule(),
    getBillingAccountModule(),
    // The following four should be nested within 
    getCustomerModule(),
    getEnrollmentRecordsModule(),
    getOrdersModule(),
    getPaymentObligationsModule(),
    {
      id: ID,
      reducerMap: {
        [ID]: reducer,
      },
      sagas: [
        customerDetailsPageSagas,
      ],
    },
  ]
}

As an example of a child module:

/* File: enrollmentRecords/module.js */

import reducer from './reducer'
import enrollmentRecordsSagas from './sagas'

const ID = 'enrollmentRecords'

export function getModule() {
  return {
    id: ID,
    reducerMap: {
      [ID]: reducer,
    },
    sagas: [
      enrollmentRecordsSagas,
    ],
  }
}

Now, when I load the page, my store looks like this:

Screen Shot 2020-04-17 at 10 36 25 AM

I think I know why the store parts in red are where they are (because I didn't follow https://redux-dynamic-modules.js.org/#/reference/Dependencies), but what's not clear to me is why my dependent store partitions are in both places.

dkreft commented 4 years ago

Okay, I think I understand this now.

The store partitions that I've highlighted in red in the screenshot, above, are due to this:

    // The following four should be nested within 
    getCustomerModule(),
    getEnrollmentRecordsModule(),
    getOrdersModule(),
    getPaymentObligationsModule(),

While the (properly) nested parts are due to this in my reducer:

/* File: ./reducer.js */

export default combineReducers({
  detailsPage: detailsPageReducer,
  customer: customerReducer,
  enrollmentRecords: enrollmentRecordsReducer,
  orders: customerOrdersReducer,
  paymentObligations: paymentObligationsReducer,
})

So it looks like what I need to do for my purposes is just remove the getFooModule() parts from the config, and roll-up all my subordinate sagas in my ./sagas.js and reduce my configuration down to this:

export function getModule() {
  return [
    getAssignableUsersModule(),
    getBillingAccountModule(),
    {
      id: ID,
      reducerMap: {
        [ID]: reducer,
      },
      sagas: [
        customerDetailsPageSagas,
      ],
    },
  ]
}

Does that sound about right?