<aside> ℹ️ Learn more about Redux stores, and plugins:

How to Work with Redux?

How to work with plugins?

</aside>

Plugins can be used to extend a reducer. For example, they can add new action types or modify the return values of specific actions.

How to add a new action to the reducer?

  1. Import the action from a specific path.
  2. Create a function that will extend the reducer’s default behavior
  3. Plugin into the reducer namespace
// can be any action. out newly created or the one from ScandiPWA source code 
import { UPDATE_CONFIG } from 'SourceStore/Config/Config.action';

const <u>**getSomeValueFromAction**</u> = (args, callback) => {
		// callback(...args) - if default result from the function's callback,
		// in our case the return value from ConfigReducer
    const result = callback(...args);
		// state can be omitted if not necessary, like so: 
		// const [, action] = args;
    const [state, <u>**action**</u>] = args;

		// destructure <u>**action**</u> to get necessary values from it
		// for example if we want to get <u>**someValue**</u> from action's config value
		const {
        type,
        config: {
            <u>**someValue**</u>
        } = {}
    } = <u>**action**</u>;

		// add early return condition, where we will check if
		// <u>**action**</u>'s type is different from the one we are trying to modify
		if (type !== UPDATE_CONFIG) {
        return result;
    }
		
		// new return value for our action type: UPDATE_CONFIG
		// where we spread the result object and add new value - someValue
    return {
        ...result,
        <u>**someValue**</u>
    };
});

// copy the namespace from the reducer you're trying to plug in into
export const config = {
   'Store/Config/Reducer': {
        function: <u>**getSomeValueFromAction**</u>
    }
};

export default config;

You can add a new action type using the same steps, but instead of using a single if condition, you can utilize a switch statement, as in the following example:

// replace CustomAction with your action
import { CUSTOM_ACTION } from 'PATH_TO/CUSTOM_ACTION/CUSTOM_ACTION.action';
import { UPDATE_CONFIG } from 'SourceStore/Config/Config.action';

const getSomeValueFromAction = (args, callback) => {
	const result = callback(...args);
	const [state, action] = args;
	const { someValue: prevSomeValue = {} } = state;
	
	const {
	  type,
	  config: {
	      someValue
	  } = {},
		newProperty
	} = action;
	
	switch (type) {
  case UPDATE_CONFIG:
      return {
          ...result,
          someValue
      };

  case CUSTOM_ACTION:
      return {
          ...result,
          someValue: {
              ...prevSomeValue,
					    newProperty
					 // ^^^ short for
					 // newProperty: newProperty
          }
      };
  default:
      return result;
  }
}

export const config = {
	'Store/Config/Reducer': {
		function: getSomeValueFromAction
	}
};

export default config;