<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ pcf - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ pcf - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 27 Jul 2026 15:22:30 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/pcf/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Use React 19 in Power Apps PCF Components ]]>
                </title>
                <description>
                    <![CDATA[ The Power Apps Component Framework – PCF for short – lets you create complex custom components using traditional web development tools like HTML, CSS, and JavaScript. When creating a new PCF project,  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-react-19-in-pcf-components/</link>
                <guid isPermaLink="false">6830767c62d9a28c0de11007</guid>
                
                    <category>
                        <![CDATA[ powerapps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pcf ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 23 May 2025 13:22:04 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747861011004/173ecdcd-7bca-4c4f-967b-47616bd79a06.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Power Apps Component Framework – PCF for short – lets you create complex custom components using traditional web development tools like HTML, CSS, and JavaScript.</p>
<p>When creating a new PCF project, you can choose from two types of controls: <strong>standard controls</strong> and <strong>React virtual controls</strong>. For non-trivial components, React is often a good choice because it abstracts away much of the heavy DOM manipulation. But, when you’re using React with PCF, you’re currently limited to React 16 in Canvas apps and React 17 in Model-Driven apps.</p>
<p>That doesn’t mean you <em>can’t</em> use a newer version – but doing so means opting out of virtualization support. For many PCF components, that trade-off is usually acceptable.</p>
<p>In this article, I’ll show you how to integrate the latest version of React (v19) with your PCF component. We’ll install the necessary dependencies and configure the component to take full advantage of the latest version of React.</p>
<h3 id="heading-this-article-assumes-that-you">This article assumes that you:</h3>
<ul>
<li><p>Understand how to use the PAC CLI to create PCF projects.</p>
</li>
<li><p>Are comfortable using the command line and a code editor (for example, VS Code)</p>
</li>
<li><p>Know the basics of React</p>
</li>
<li><p>Have some experience with PCF development</p>
</li>
</ul>
<p>Note: You don’t need access to a Power Platform environment unless you want to deploy the component. The built-in test harness will be sufficient to follow along with this article.</p>
<h3 id="heading-in-this-tutorial-you-will">In this tutorial, you will:</h3>
<ul>
<li><p><a href="#heading-create-a-pcf-project">Create a PCF Project</a></p>
</li>
<li><p><a href="#heading-install-the-react-dependencies">Install the React Dependencies</a></p>
</li>
<li><p><a href="#heading-create-a-non-react-button">Create a Non-React Button</a></p>
</li>
<li><p><a href="#heading-create-a-react-button">Create a React Button</a></p>
</li>
<li><p><a href="#heading-add-the-react-button-to-the-pcf-component">Add the React Button to the PCF Component</a></p>
</li>
<li><p><a href="#heading-render-the-react-button-when-the-pcf-component-updates">Render the React Button When the PCF Component Updates</a></p>
</li>
</ul>
<h2 id="heading-create-a-pcf-project">Create a PCF Project</h2>
<p>To create a PCF project, you’ll use the <strong>PAC CLI</strong>. If you haven’t installed it yet, follow the instructions <a href="https://learn.microsoft.com/en-us/power-platform/developer/cli/introduction?tabs=windows">here</a>.</p>
<p>From the directory of your choice, create a new folder for this project, and then open your terminal and run:</p>
<pre><code class="language-bash">pac pcf init -ns SampleNameSpace -n SampleComponent --template field
</code></pre>
<p>Once it finishes, run:</p>
<pre><code class="language-bash">npm install
</code></pre>
<p>This installs the default project dependencies.</p>
<p>So why didn’t we use the <code>--framework</code> flag to specify React during project creation? Because that flag sets up a React virtual control, which only supports React 16/17. Instead, we’re creating a standard control and installing React ourselves.</p>
<h2 id="heading-install-the-react-dependencies">Install the React Dependencies</h2>
<p>To use React 19, you’ll need four dependencies:</p>
<ul>
<li><p><code>react</code></p>
</li>
<li><p><code>react-dom</code></p>
</li>
<li><p><code>@types/react</code></p>
</li>
<li><p><code>@types/react-dom</code></p>
</li>
</ul>
<p>These last two provide TypeScript typings for React. Install the above dependencies with:</p>
<pre><code class="language-bash">npm install -D react react-dom @types/react @types/react-dom
</code></pre>
<p>You can verify the installation by looking at the <code>package.json</code> file in the project.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747410603816/a7eeeb60-dcbe-49c9-9913-6319cd246333.png" alt="The package.json file showing the react dependencies installed." style="display:block;margin:0 auto" width="1671" height="940" loading="lazy">

<p>While not necessary for what we will be doing, in order to use some newer React features, you may need to tweak the <code>compilerOptions</code> in the <code>tsconfig.json</code> file to include the line below:</p>
<pre><code class="language-json">"jsx": "react-jsx"
</code></pre>
<p>Here is what the <code>tsconfig.json</code> file should look like with the added <code>jsx</code> line:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747410782472/524ac9a6-3898-4427-8bab-090fe0a3f718.png" alt="524ac9a6-3898-4427-8bab-090fe0a3f718" style="display:block;margin:0 auto" width="1820" height="614" loading="lazy">

<h2 id="heading-create-a-non-react-button">Create a Non-React Button</h2>
<p>Let’s verify that everything works before we introduce React.</p>
<p>From the command line, run:</p>
<pre><code class="language-bash">npm run start:watch
</code></pre>
<p>This may take a moment. It will open a browser showing your PCF test harness. You’ll likely see an empty screen. That’s expected – we haven’t rendered anything yet.</p>
<p>Open <code>index.ts</code> in the <code>SampleComponent</code> folder. This file contains a class that implements the PCF standard control interface. Let’s create a basic non-React button.</p>
<p>Update the <code>init</code> method in the <code>index.ts</code> file like this:</p>
<pre><code class="language-typescript">public init(
    context: ComponentFramework.Context&lt;IInputs&gt;,
    notifyOutputChanged: () =&gt; void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
): void {
    // A basic button with vanilla JS and the DOM
    const btn = document.createElement('button');
    btn.textContent = 'Click me!';
    container.appendChild(btn);

    // A simple event lister for button clicks
    btn.addEventListener('click', () =&gt; {
        alert('Button clicked!');
    });
}
</code></pre>
<p>Now, head back to your test harness. You should see a button. Clicking it should display an alert.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747411524929/36d26f79-1d48-403c-9005-56655a16ed04.png" alt="PCF test harness with clickable button." style="display:block;margin:0 auto" width="1918" height="998" loading="lazy">

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747411544199/85aab788-1a02-439c-8597-d74d6fa3a39c.png" alt="PCF test harness with alert displayed after button was clicked." style="display:block;margin:0 auto" width="1918" height="998" loading="lazy">

<h2 id="heading-create-a-react-button">Create a React Button</h2>
<p>Next, let’s replace our plain DOM code with React.</p>
<p>Delete the button code from <code>init()</code>, leaving the <code>init</code> method empty.</p>
<p>Then, create a new file: <code>Button.tsx</code>. Inside <code>Button.tsx</code>, add the code below. This component will accept a label prop and emit an <code>onClick</code> event. Make sure to export the function.</p>
<pre><code class="language-typescript">export default function Button(props: { label: string; onClick: () =&gt; void }) {
    return &lt;button onClick={props.onClick}&gt;{props.label}&lt;/button&gt;;
}
</code></pre>
<h2 id="heading-add-the-react-button-to-the-pcf-component">Add the React Button to the PCF Component</h2>
<p>In <code>index.ts</code>, update the file to:</p>
<ol>
<li><p>Import <code>createRoot</code> from <code>react-dom/client</code></p>
</li>
<li><p>Import the <code>Button</code> component</p>
</li>
<li><p>Render the <code>Button</code> component</p>
</li>
</ol>
<p>Here is the minimal example:</p>
<pre><code class="language-typescript">import { createRoot } from 'react-dom/client'; // import the createRoot method
import Button from './Button'; //import the button.tsx component we just created

export class SampleComponent
    implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt;
{
    constructor() {
        // Empty
    }
    public init(
        context: ComponentFramework.Context&lt;IInputs&gt;,
        notifyOutputChanged: () =&gt; void,
        state: ComponentFramework.Dictionary,
        container: HTMLDivElement
    ): void {
        // Add the code below to create a React root that allows us to render our button component.
        const root = createRoot(container);
        root.render(
            Button({ label: 'React Button', onClick: () =&gt; alert('React Button Clicked!') })
        );
    }
    // Other methods here...
}
</code></pre>
<p>You should now see “React Button” in the browser. Clicking it will trigger the alert.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747412200377/ef496e75-de8f-4abe-8371-25dd295ee057.png" alt="PCF test harness with the React button" style="display:block;margin:0 auto" width="1905" height="987" loading="lazy">

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747412239139/d4c73764-667f-445c-9366-aa270e456d13.png" alt="PCF test harness with alert displayed after the React buttons was clicked." style="display:block;margin:0 auto" width="1918" height="998" loading="lazy">

<h2 id="heading-render-the-react-button-when-the-pcf-component-updates">Render the React Button When the PCF Component Updates</h2>
<p>Many PCF components receive dynamic input values. If the inputs change, we want the React component to re-render. This is where <code>updateView()</code> comes in. <code>updateView()</code> is triggered when the PCF property bag changes.</p>
<p>Let’s move the rendering logic from <code>init()</code> to <code>updateView()</code>.</p>
<p>First, import <code>Root</code> from <code>react-dom/client</code>, and initialize <code>root</code> as a property of the class.</p>
<pre><code class="language-typescript">import { createRoot, Root } from 'react-dom/client'; //add Root as an import

export class SampleComponent implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt; {
    root: Root; // initialize the root property on the SampleComponent class
    constructor() {
        // Empty
    }
    // other methods here...
}
</code></pre>
<p>Then, modify <code>init()</code> to set <code>this.root</code> to the root created by React’s <code>createRoot</code> method. Move the rendering logic from the <code>init</code> method to <code>updateView()</code>, replacing <code>root</code> with <code>this.root</code>.</p>
<pre><code class="language-typescript">public init(
    context: ComponentFramework.Context&lt;IInputs&gt;,
    notifyOutputChanged: () =&gt; void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
    ): void {
        this.root = createRoot(container); // assign the root React creates to this.root
    }

public updateView(context: ComponentFramework.Context&lt;IInputs&gt;): void {
    // render the React button component, by referencing this.root
    this.root.render(
        Button({ label: 'React Button', onClick: () =&gt; alert('Button Clicked!') })
    );
}
</code></pre>
<p>With the above setup, React will now re-render your button when the property bag of a PCF component changes.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You’ve now created a PCF component that uses the latest version of React! By installing and configuring React manually, you avoid the version limitations of Microsoft’s built-in React controls – unlocking the power of modern React features.</p>
<p>While this setup doesn’t support virtualization, for many components that’s a fair trade-off for modern tooling and maintainability.</p>
<p>If you’re building PCF components beyond simple DOM manipulation, React can be a powerful way to improve your development workflow and UI flexibility.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
