{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/power-apps-component-framework-pcf-reuso-controles/","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Power Apps Component Framework: reuso de UI corporativa com PCF","description":"Construir controles PCF vai muito além de estilizar campos: entenda o ciclo de vida do componente, dataset vs field controls, empacotamento e ALM para reusar UI em toda a organização.","date":"15 de setembro de 2026","thumbnail":null},"html":"<p>O Power Apps Component Framework (PCF) costuma ser lembrado como \"aquele jeito de deixar um campo mais bonito\". Mas quando uma organização tem dezenas de model-driven apps e formulários compartilhando os mesmos padrões de interface — um seletor de status com cores, um mapa, um grid customizado com edição inline — o PCF deixa de ser cosmético e vira uma estratégia de reuso de UI de verdade. Este post foca no que muda quando você trata code components como um ativo de plataforma, e não como um hack pontual em um formulário.</p>\n<p><strong>Field control vs dataset control: a decisão que define tudo</strong></p>\n<p>Antes de escrever qualquer linha de TypeScript, você escolhe o tipo de componente no manifest (<code>ControlManifest.Input.xml</code>), e essa escolha condiciona toda a arquitetura:</p>\n<ul>\n<li><strong>Field control</strong> — vinculado a uma única coluna do formulário. O componente recebe e devolve um valor (<code>context.parameters.&#x3C;campo></code>), e é o caso do slider, do color picker, do input mascarado. Simples, mas limitado a um dado por vez.</li>\n<li><strong>Dataset control</strong> — vinculado a uma view ou subgrid, recebe uma coleção de registros com paginação, ordenação e filtros. É o que permite substituir o grid nativo por uma renderização própria (kanban, calendário, timeline) mantendo as capacidades de dados do Dataverse.</li>\n</ul>\n<p>O erro clássico é começar um field control e, no meio do caminho, perceber que o requisito era sobre múltiplos registros — o que obriga a refazer o manifest e boa parte da lógica. Defina isso primeiro.</p>\n<p><strong>O ciclo de vida é o contrato que você precisa respeitar</strong></p>\n<p>Um code component não é um componente React solto: ele obedece a um ciclo de vida que o host (o formulário ou o canvas app) controla. Os quatro métodos do <code>index.ts</code> importam:</p>\n<ol>\n<li><code>init</code> — recebe o <code>context</code>, o callback <code>notifyOutputChanged</code> e o container DOM. É onde você monta a estrutura inicial. Não faça chamadas pesadas aqui.</li>\n<li><code>updateView</code> — chamado toda vez que qualquer parâmetro muda (dado, tamanho do container, modo de leitura). É o coração do componente e precisa ser idempotente: renderizar sempre a partir do <code>context</code> atual, sem acumular estado escondido.</li>\n<li><code>getOutputs</code> — devolve ao host os valores que o componente alterou; só é chamado depois de você invocar <code>notifyOutputChanged</code>.</li>\n<li><code>destroy</code> — libera listeners, timers e instâncias. Ignorar isso em componentes que entram e saem da tela (subgrids, quick view forms) causa memory leaks silenciosos.</li>\n</ol>\n<p>Quem vem de React puro tende a tratar <code>updateView</code> como um <code>useEffect</code> qualquer e esquece que o framework pode chamá-lo com muito mais frequência do que espera. Renderizações caras precisam de guarda por comparação de valores relevantes.</p>\n<p><strong>Acesso a dados: use as APIs do context, não fetch direto</strong></p>\n<p>A tentação de disparar um <code>fetch</code> para a Web API a partir do componente é grande, mas o framework oferece <code>context.webAPI</code> justamente para respeitar segurança, business units e o token da sessão. Além disso:</p>\n<ul>\n<li><code>context.webAPI.retrieveMultipleRecords</code> respeita as security roles do usuário — um fetch manual com URL montada na mão pode quebrar em ambientes com column security ou expor chamadas fora do padrão de auditoria.</li>\n<li>Para dataset controls, prefira consumir o próprio dataset paginado (<code>context.parameters.&#x3C;dataset>.paging</code>) em vez de recarregar tudo — você herda os filtros da view e o comportamento de scroll.</li>\n<li>Chamadas assíncronas devem sempre revalidar contra o <code>context</code> no retorno, porque o registro em foco pode ter mudado enquanto a promise resolvia.</li>\n</ul>\n<p><strong>Empacotamento e ALM: onde a maioria dos projetos tropeça</strong></p>\n<p>Um PCF só vira ativo corporativo quando entra no ciclo de ALM da plataforma. Isso significa:</p>\n<ul>\n<li>Buildar o componente e importá-lo dentro de uma <strong>solução gerenciada</strong>, não fazer <code>pac pcf push</code> direto em produção (esse comando é para o loop de desenvolvimento, não para deploy).</li>\n<li>Versionar o componente no manifest com disciplina, porque atualizações de code component são globais — subir uma versão nova reflete em todos os formulários que o usam. Uma regressão vira incidente em vários apps ao mesmo tempo.</li>\n<li>Habilitar o feature de code components no ambiente (Power Apps component framework precisa estar ligado nas configurações do ambiente para model-driven, e é obrigatório para canvas).</li>\n<li>Tratar o repositório do PCF como código de verdade: pipeline com <code>npm run build</code>, lint, e a geração do <code>.zip</code> da solução automatizada, integrando aos Power Platform Pipelines ou ao Azure DevOps.</li>\n</ul>\n<p><strong>Quando NÃO usar PCF</strong></p>\n<p>Code component é poderoso, mas carrega custo de manutenção (build, versionamento, testes de compatibilidade a cada release da plataforma). Pense duas vezes se:</p>\n<ul>\n<li>O requisito se resolve com business rules, colunas de formatação nativa ou um formulário bem desenhado — não crie um controle para o que a plataforma já faz.</li>\n<li>A lógica é de negócio (validação, cálculo), que pertence a plugin ou business rule no servidor, não à camada de UI.</li>\n<li>O componente seria usado uma única vez em um único formulário — o ROI raramente compensa contra client scripting em JavaScript para casos pontuais.</li>\n</ul>\n<p>O ganho real do PCF aparece na escala: um controle bem construído e governado por solução, reaproveitado em dezenas de telas, com identidade visual consistente e comportamento previsível.</p>\n<p>Estruturar code components como ativos de plataforma — com manifest correto, ciclo de vida respeitado e ALM disciplinado — é o tipo de decisão de arquitetura que separa um Power Apps que escala de uma coleção de gambiarras de UI. Se a sua empresa está ampliando o uso de model-driven apps e quer padronizar a experiência com componentes reutilizáveis e governados, a equipe da Dynamic Soluções pode ajudar a desenhar essa camada e integrá-la ao seu ciclo de ALM.</p>\n<p>The Power Apps Component Framework (PCF) is usually remembered as \"that way to make a field look nicer.\" But when an organization runs dozens of model-driven apps and forms sharing the same interface patterns — a color-coded status picker, a map, a custom grid with inline editing — PCF stops being cosmetic and becomes a real UI reuse strategy. This post focuses on what changes when you treat code components as a platform asset rather than a one-off hack on a single form.</p>\n<p><strong>Field control vs dataset control: the decision that defines everything</strong></p>\n<p>Before writing a single line of TypeScript, you choose the component type in the manifest (<code>ControlManifest.Input.xml</code>), and that choice shapes the entire architecture:</p>\n<ul>\n<li><strong>Field control</strong> — bound to a single form column. The component receives and returns a value (<code>context.parameters.&#x3C;field></code>), and this is the case for a slider, a color picker, a masked input. Simple, but limited to one piece of data at a time.</li>\n<li><strong>Dataset control</strong> — bound to a view or subgrid, it receives a collection of records with paging, sorting and filters. This is what lets you replace the native grid with your own rendering (kanban, calendar, timeline) while keeping Dataverse's data capabilities.</li>\n</ul>\n<p>The classic mistake is starting a field control and, midway through, realizing the requirement was about multiple records — which forces you to rebuild the manifest and much of the logic. Decide this first.</p>\n<p><strong>The lifecycle is a contract you have to honor</strong></p>\n<p>A code component isn't a loose React component: it follows a lifecycle controlled by the host (the form or canvas app). The four methods in <code>index.ts</code> matter:</p>\n<ol>\n<li><code>init</code> — receives the <code>context</code>, the <code>notifyOutputChanged</code> callback and the DOM container. This is where you build the initial structure. Don't make heavy calls here.</li>\n<li><code>updateView</code> — called every time any parameter changes (data, container size, read mode). It's the heart of the component and must be idempotent: always render from the current <code>context</code>, without accumulating hidden state.</li>\n<li><code>getOutputs</code> — returns to the host the values the component changed; it's only called after you invoke <code>notifyOutputChanged</code>.</li>\n<li><code>destroy</code> — releases listeners, timers and instances. Ignoring this in components that enter and leave the screen (subgrids, quick view forms) causes silent memory leaks.</li>\n</ol>\n<p>People coming from plain React tend to treat <code>updateView</code> like any <code>useEffect</code> and forget that the framework may call it far more often than expected. Expensive renders need guards based on comparing the relevant values.</p>\n<p><strong>Data access: use the context APIs, not raw fetch</strong></p>\n<p>The temptation to fire a <code>fetch</code> at the Web API from within the component is strong, but the framework offers <code>context.webAPI</code> precisely to respect security, business units and the session token. On top of that:</p>\n<ul>\n<li><code>context.webAPI.retrieveMultipleRecords</code> respects the user's security roles — a hand-built manual fetch may break in environments with column security or expose calls outside the audit standard.</li>\n<li>For dataset controls, prefer consuming the paged dataset itself (<code>context.parameters.&#x3C;dataset>.paging</code>) instead of reloading everything — you inherit the view's filters and scroll behavior.</li>\n<li>Async calls should always revalidate against the <code>context</code> on return, because the record in focus may have changed while the promise was resolving.</li>\n</ul>\n<p><strong>Packaging and ALM: where most projects stumble</strong></p>\n<p>A PCF only becomes a corporate asset when it enters the platform's ALM cycle. That means:</p>\n<ul>\n<li>Building the component and importing it inside a <strong>managed solution</strong>, not running <code>pac pcf push</code> straight into production (that command is for the development loop, not deployment).</li>\n<li>Versioning the component in the manifest with discipline, because code component updates are global — pushing a new version reflects across every form using it. A regression becomes an incident in several apps at once.</li>\n<li>Enabling the code components feature in the environment (Power Apps component framework must be turned on in the environment settings for model-driven, and it's mandatory for canvas).</li>\n<li>Treating the PCF repository as real code: a pipeline with <code>npm run build</code>, lint, and automated generation of the solution <code>.zip</code>, integrated into Power Platform Pipelines or Azure DevOps.</li>\n</ul>\n<p><strong>When NOT to use PCF</strong></p>\n<p>Code components are powerful, but they carry a maintenance cost (build, versioning, compatibility testing on every platform release). Think twice if:</p>\n<ul>\n<li>The requirement is solved with business rules, native formatting columns or a well-designed form — don't build a control for what the platform already does.</li>\n<li>The logic is business logic (validation, calculation), which belongs in a plugin or server-side business rule, not in the UI layer.</li>\n<li>The component would be used just once on a single form — the ROI rarely beats plain JavaScript client scripting for point cases.</li>\n</ul>\n<p>PCF's real payoff shows up at scale: a well-built control governed by a solution, reused across dozens of screens, with consistent visual identity and predictable behavior.</p>\n<p>Structuring code components as platform assets — with the right manifest, a respected lifecycle and disciplined ALM — is the kind of architecture decision that separates a Power Apps that scales from a collection of UI workarounds. If your company is expanding its use of model-driven apps and wants to standardize the experience with reusable, governed components, the Dynamic Soluções team can help design that layer and integrate it into your ALM cycle.</p>"}},"pageContext":{"slug":"/blog/power-apps-component-framework-pcf-reuso-controles/","previousPost":null,"nextPost":{"frontmatter":{"title":"Power BI: field parameters para relatorios dinamicos e enxutos"},"fields":{"slug":"/blog/power-bi-field-parameters-relatorios-dinamicos/"}}}},"staticQueryHashes":["2269431855"]}