In the first blogpost in this series I covered the basics on how to create a PCF component. In this blogpost I will show you how to add React to PCF component, how to test the component in an Canvas app, and how to add a dataset resouce and connect it to a table in Dataverse.
A comprehensive guide to Power Apps Component framework
Note, the other posts will be published in the next couple of weeks. The links will be updated – if the link is not active it is because the post is not published yet.
Table of content
- Creating your component and adding React
- Deploying the PCF component and adding it to a canvas app
- Working with a datasource (dataset from dataverse table)
- Resources
Creating your component and adding React
I’ll also assume that you know basic React and TypeScript.
You can find the full sourcecode for this sample on github
Initialize and create your PCF project
In your prefered CLI navigate to the folder where you want to create your project and run the below command.
pac pcf init -n "PCF React Demo" -ns "namespace" -t dataset
When the project is generated install react, react-dom and react types dependencies.
//Installs the core react packages npm install react react-dom //Install the type defintions for the above packages as dev dependencies npm install --save-dev @types/react @types/react-dom
Now lets create a simple React component and display it in the PCF component.
I prefer to create a folder “components” to keep the React components.
Create a file named “MyReactComponent.tsx”. Inside the file create a simple functional component that returns a h2 element with “Hello React”.
import * as React from "react"; interface IMyReactComponentProps {} const MyReactComponent: React.FC<IMyReactComponentProps> = () => { return ( <h2>Hello React</h2> ); }; export default MyReactComponent;
Now we need to render the React component from our index.ts file.
- In the top of the file import React and ReactDOM.
- Create a private variable for
_container
. In the init function set the value of the private _container variable to be the container the init funcitons get as a parameter. - In the updateView function use
ReactDOM
andReact.createElement
to create and render “MyReactComponent”.
import * as React from "react"; import * as ReactDOM from "react-dom"; /** THIS CODE IS SHORTENED FOR READABILITY.. SEE FULL SOURCE CODE FOR THE COMPLETE FILE **/ export class PCFReactDemoimplements ComponentFramework.StandardControl<IInputs, IOutputs>{ private _container: HTMLDivElement; ... public init(context: ComponentFramework.Context<IInputs>,notifyOutputChanged: () => void,state: ComponentFramework.Dictionary,container: HTMLDivElement): void { this._container = container; } public updateView(context: ComponentFramework.Context<IInputs>): void { ReactDOM.render( React.createElement(MyReactComponent, {}), this._container ); } ... }
And thats it. If you run npm start watch you will see your React component rendered as part of your PCF component.
Deploying the PCF component and adding it to a canvas app
First you need to establish a auth connection to your environment. You do this by running the pac auth create
command and passing the environment url as a parameter.
pac auth create --url https://myenvironment.crm4.dynamics.com
If you have multiple auth connections set up you can see which one is active by running pac auth list
.
The one with the *
is the active connection.
To cange the connection use pac auth select
command and pass in --index
as a parameter
pac auth select --index 2
When the connection is established you can run pac pcf push
to push your component to the environment.
pac pcf push --publisher-prefix [your_prefix_here]
Adding your component to a canvas app
In your browser go to https://make.powerapps.com/ . And select “Create canvas app”.
When the app editor is opened select +
in the left side menu. And then “Get more components” as shown in the images below.
This will open up a panel to the right in the app editor. Here, select “Code”, and select your component from the list.
If you go back to the right side panel your component will show up under “Code components”. And you can add it to your app by clicking it, or dragging it over to the canvas.
Updating your PCF component
If you make some changes to your component and want to push the changes to your canvas app you must remember to increment the version number in the PCF component manifest or the canvas app will keep using the old version. You can read more about the manifest and the other files in part 1 of this series.
Working with a datasource
As I mentioned in the first part of this blogpost series you can create a PCF component of type field or dataset. In this example I want to show you how to connect to a dataverse table and use the app-context and the dataset that is provided there to list the content of a column in your table.
First, navigate to the dataverse table you want to work with and get the internal name of the column, in my demo table that name is “cr933_name” as highlightet in the image below.
Now lets change our react component to take the app context as a prop.
import * as React from "react"; import { IInputs } from "../generated/ManifestTypes"; interface IMyReactComponentProps { appContext: ComponentFramework.Context<IInputs>; } const MyReactComponent: React.FC<IMyReactComponentProps> = ({ appContext }) => { return ( <section> <h2>Hello datasource</h2> </section> ); }; export default MyReactComponent;
We also need to pass the app-context to the react element from the index.ts file.
- Add a new private variable called _context, and give it the type ComponentFramework.Context<IInputs> (line 2 in the snippet below)
- In the init functin set the value of _context to be the context that is passed in as a parameter (line 8 in the snippet)
- Send the context in as a prop to the React element. (line 14 in the snippet)
export class PCFReactDemo implements ComponentFramework.StandardControl<IInputs, IOutputs>{ private _context: ComponentFramework.Context<IInputs>; private _container: HTMLDivElement; ... /** THIS CODE IS SHORTENED FOR READABILITY.. SEE FULL SOURCE CODE FOR THE COMPLETE FILE **/ public init(context: ComponentFramework.Context<IInputs>,notifyOutputChanged: () => void,state: ComponentFramework.Dictionary,container: HTMLDivElement): void { this._context = context; this._container = container; } public updateView(context: ComponentFramework.Context<IInputs>): void { // Add code to update control view ReactDOM.render(React.createElement(MyReactComponent, { appContext: this._context }), this._container) } ...
How to access the dataset in your React component
The react component now recieves the appContext as a parameter. And this appContext has its own parameters – and one of them is the dataset from your manifest. In my case the dataset is named “sampleDataSet”, so I access it by writing appContext.parameters.sampleDataSet
.
The dataset has its own variables and functions and we will use the sortedRecordIds function to map through the records in the dataset and get the value of each records name column (line 9-12 in the code snippet below).
import * as React from "react"; import { IInputs } from "../generated/ManifestTypes"; interface IMyReactComponentProps { appContext: ComponentFramework.Context<IInputs>; } const MyReactComponent: React.FC<IMyReactComponentProps> = ({ appContext }) => { const dataSet = appContext.parameters.sampleDataSet; const allRecords = dataSet.sortedRecordIds.map((record) => { return <div>{dataSet.records[record].getValue("cr933_name")}</div>; }); return ( <section> <h2>Hello datasource</h2> {allRecords} </section> ); }; export default MyReactComponent;
When you add your PCF component to your canvas app you will be promted to select a datasource. Select the table you would like to connect to:
And now the PCF component will render the data from my Demo table.
Below you can see the PCF component to the left, and the Demo Dataset Table to the right.
Summary
In this blogpost I covered how to add React to your PCF component, how to deploy and test the component in a canvas app, and how to use a dataset to connect to a table in dataverse.
If you found this post useful you might like my other blogposts about PCF as well. I also recommend you take a look at the resouces listes below.
Resources
- Power App Component Framwork overview (Microsoft docs)
- Best practices for code components created using Power Apps Component Framework (PCF) (Microsoft docs)
- Add component to a canvas app (Microsoft docs)
- Sample components (Microsoft docs)
Did you find this article usefull? Follow me on twitter to be notified when I publish something new!
If you are interested in Microsoft 365 Development you might also like my other blogposts in this category.
Also, if you have any feedback or questions, please let me know in the comments below. 🙂
Thank you for reading, and happy coding!
/Eli
If you want to support my content you can
Hej Eli, thank you very much for this guide! I’m learning PCF right now and this guide is exactly what I needed to understand PCFs in more depth. One thing to note: if you will be able to use your PCFs in a canvas app, you have to enable the feature “Allow publishing of canvas apps with code components” in the settings of your environment. Otherwise the “Code” tab in the “import components” menu is missing.
Thanks for the feedback! I will update my blogpost to include this information 🙂
Thanks Eli , this is great, I’m just starting to learn this and I’m trying to follow the steps you outlined, but I’m facing some issues
This is the error I get on build.log when trying to push this onto a dev enviroment :
error : [pcf-1014] [Error] Manifest validation problem: instance.manifest.control[0].data-set[0].property-set[0].$.of-type is not one of enum values…
Also getting an error on the tsx component from the github repo … return {dataSet.records[record].getValue.
Probably I’m doing something wrong 🙂
Hi! Thanks for the feedback!
I tried to run the sample myself and I also get the first error. Its because the property-set type is set to of-type=”MultiLine.Text”. This was not a problem when I initially wrote the blogpost so I’m not sure why it stopped working. The fix is to edit this to Singleline. I also updated the github repo with this change.
The other error on the tsx component I’m not able to recreate, so I need more information about what type of error you get before I can help you with that one 🙂 It might be that you need to run a “npm run build” to make the component aware of the properties from the manifest (you need to fix the first error before build will run).