Objective Redux

Redux made better, objectively.

Lazy Loading Webpack Modules

Objective-Redux makes it simple to dynamically load webpack modules, connect their controllers, and fire actions.

Load bundles at runtime when an action targets a controller in the bundle

For example, suppose that you want to render a modal when the user clicks on a button, but you don't want to include the modal and its associated controllers on page load. Objective-Redux can listen to the action the button fires, load the webpack module that handles the action, then handle the action normally.

As a pre-requisite, you'll need to code split the controller(s) that will be bundled and targeted separately.

To setup, we define a pre-dispatch hook and pass it to the ObjectiveStore. This function takes an action as a parameter and can return either a promise (if the action should wait until the promise resolves to be fired) or null (if the action should be fired immediately).


  import React from 'react';
  import ReactDOM from 'react-dom';
  import { ObjectiveStoreProvider, ObjectiveStore } from 'objective-redux';
  import App from './app';

  // We create a pre-dispatch hook, which is function that returns a promise.
  // The promise should resolve when the app is ready for the action to be fired.
  const preDispatchHook = (action) => {
    let result = Promise.resolve();

    switch (action.type) {
      case myAction:
        result = import(/* webpackChunkName: "lazyLoadingPack" */ './lazy-loaded-module');
        break;
      // other actions here
    }

    return result;
  }
  
  export const objectiveStore = new ObjectiveStore({
    preDispatchHook,
  });
  
  ReactDOM.render(
    <ObjectiveStoreProvider objectiveStore={objectiveStore}>
      <App />
    </ObjectiveStoreProvider>,
    document.getElementById('root')
  );

Now, we can simply fire the action targeting our ObjectiveRedux controller normally.


  import React from 'react';
  import {
    useObjectiveStore,
    createAction,
    getActionNameForController,
  } from 'objective-redux';
  
  const myAction = createAction(
    getActionNameForController('MyController', 'MyAction');
  );

  function ButtonComponent() {
    const objectiveStore = useObjectiveStore();

    const fireAction = () => {
      objectiveStore.dispatch(myAction());
    }
  
    return (
        <button onClick={fireAction}>
          Click to target an action in another bundle
        </button>
    );
  }

Now, when the button is clicked:

  1. The webpack bundle is loaded
  2. The Objective-Redux controllers in the bundle are registered
  3. The controller handling the action is instantiated (its reducers are connected/sagas are run)
  4. The action is fired

See the working example in the public GitHub repository.