Sometimes, you may need a component to have access to global states, reducers, or dispatchers that are not defined in the container mapStateToProps or mapDispatchToProps.
<aside>
⚠️ Some containers may not have the mapStateToProps or mapDispatchToProps functions defined for you to extend. For example, the Field container in ScandiPWA does not have them. In such cases, you can use the getStore method from the util/Store directory to access the Redux state and dispatch when extending the component.
</aside>
One option would be to override the component, but it is almost never a good idea. In most cases, it’s better to extend the component by using plugins.
This tutorial is assuming as an example that you want to make the Checkout component able to access:
config and chart from the SizeChartReducer as propsgetSizeChartConfig from the SizeChartDispatcher as a prop updateSizeChartConfigresetSizeChart action as a prop resetSizeChartTo better understand this tutorial, you can read the following pages:
To plugin into mapStateToProps and mapDispatchToProps you need to:
mapStateToProps and mapDispatchToPropsScandiPWA follows a pattern for naming plugins and determining their location. In this case, the original file that defines the mapStateToProps and mapDispatchToProps functions is called Checkout.container.js.
Therefore, create a file named Checkout.container.plugin.js in the src/plugin directory.
mapStateToProps and mapDispatchToPropsThis step involves creating the function to update the initial mapStateToProps and mapDispatchToProps. Since the original functions define its own namespace, when defining a plunging to then, it will accept as parameters the args and the callback.
The contents of args will vary depending on the original function. In mapStateToProps, it contains state, and in mapDispatchToProps, it contains dispatch. You should use these and return the new desired object.
When naming functions, use descriptive names. This will be helpful when someone needs to debug the application. This tutorial will define addChartStatesToMapStateToProps and addSizeDispatcherToMapDispatchToProps(probably could be better).
<aside>
🚨 Avoid not using the callback(...args) function, unless absolutely necessary.
</aside>
mapStateToProps?The args content includes the state object that is passed to the original mapStateToProps function. You should use it to define the states that you want to have.
const addChartStatesToMapStateToProps = (args, callback) => {
const [state] = args;
const { SizeChartReducer: { config, chart } } = state;
return {
...callback(...args),
sizeChartConfig: config,
sizeChart: chart
};
};
mapDispatchToProps?The args content contains the dispatch object that is passed to the original mapDispatchToProps function. You should use it to define dispatchers or functions that dispatch an action as props.
import SizeChartDispatcher from '../store/SizeChart.dispatcher';
import { resetSizeChart } from '../store/SizeChart.action';
const addSizeDispatcherToMapDispatchToProps = (args, callback) => {
const [dispatch] = args;
return {
...callback(...args),
updateSizeChartConfig: () => SizeChartDispatcher.getSizeChartConfig(dispatch),
resetSizeChart: () => dispatch(resetSizeChart())
};
};
To finalize the implementation, you need to export an object that maps the original function to the function you want to plug in.
For this step is necessary to have the namespace of the original function. The namespace is defined right above the original function definition.
By studying the original ScandiPWA’s Checkout container, you’ll discover that:
mapStateToProps has the namespace Route/Checkout/Container/mapStateToPropsmapDispatchToProps has the namespace Route/Checkout/Container/mapDispatchToProps<aside> ⚠️ These namespaces and functions are just examples from the tutorial. You should check the namespaces of the component you want to extend.
</aside>
export default {
'Route/Checkout/Container/mapStateToProps': {
function: addChartStatesToMapStateToProps
},
'Route/Checkout/Container/mapDispatchToProps': {
function: addSizeDispatcherToMapDispatchToProps
}
};
You have now successfully implemented a plugin for the mapStateToProps and mapDispatchToProps functions.