Quicker and easier PCF React controls with support for MVVM & unit testing
npm install pcf-reactgetOutputs() is called, this will then trigger an updateView with the same values. To avoid unnecessary rendering, we need to detect changes compared the previous values.
serviceProvider pattern with a ControlContextService that abstracts away from the base StandardControl and provides methods that can be easily mocked using jest. These methods extend to other areas such as opening records and formatting values.
ComponentFramework.StandardControl in your index.ts that is generated by pac pcf init to be StandardcontrolReact. You then no longer need the init, updateView etc. methods:
export class PCFTester extends StandardControlReact {
constructor() {
super();
this.renderOnParametersChanged = false;
this.initServiceProvider = serviceProvider => {
serviceProvider.register("", new (serviceProvider));
};
this.reactCreateElement = (container, width, height, serviceProvider) => {
ReactDOM.render(
React.createElement(, {
serviceProvider: serviceProvider,
controlWidth: width,
controlHeight: height,
}),
container,
);
};
}
}
`
The component will be rendered when any of the properties changes.
In your React component you can access the ViewModel and ControlContext using:
`
this.controlContext = props.serviceProvider.get(ControlContextService.serviceProviderName);
this.viewModel = props.serviceProvider.get("");
`
The parameters can be read using:
`
context.getParameters()
`
This allows you to using the MVVM pattern and move your logic into a ViewModel that binds to the View using mobx or redux.
Simple Dataset PCF control
`
export class PCFTesterDataset extends StandardControlReact {
constructor() {
super();
this.renderOnParametersChanged = false;
this.renderOnDatasetChanged = false;
this.initServiceProvider = (serviceProvider: ServiceProvider): void => {
serviceProvider.register("", new (serviceProvider));
};
this.reactCreateElement = (container, width, height, serviceProvider): void => {
ReactDOM.render(
React.createElement(, {
serviceProvider: serviceProvider,
controlWidth: width,
controlHeight: height,
}),
container,
);
};
}
}
`
If using mobx/redux for state management, then you can set renderOnDatasetChanged = false and in your ViewModel use:
`
this.controlContext = this.serviceProvider.get(ControlContextService.serviceProviderName);
this.controlContext.onDataChangedEvent.subscribe(this.onDataChanged);
``