25

I am refering Play Ground to render dynamic component in LWC. But it is giving error createElement is not defined.

Have any one idea how to render dynamic component. Alternative of createComponent method of Aura framework.

3 Answers 3

40

We have purposely made the decision of not allowing dynamic component creation yet (the equivalent of $A.createComponent) on the Salesforce platform to make sure we had a clean, statically analyzable and predictable behavior on which to build upon in LWC.

Note that the things we allow on the platform will always be more constraint to what you can do in LWC standalone or when is used off-platform (which will be supported officially soon).

Since the question of dynamic component creation came a bunch of times, I want to share an example of a bug that currently came to Aura long time ago that shows precisely why we decided to block it.

The following example is a simple use case where in aura you want to create dynamically (and programatically) a leaf component:

({ 
createComponent: function (component, facet, componentDef, fieldPath, attributes) { 
   // componentDef is a basic component: ex. markup://lightning:textarea
    $A.createComponent(componentDef, attributes, callback); 
    function callback(newComponent, status, errorMessage) { 
        if (status === "SUCCESS") { 
            newComponent.addValueHandler({ 
                value: "v.value",
                event: "change",
                globalId: component.getGlobalId(),

                method: function (event) { 
                    var record = component.get("v.record"); 
                    var value = event.getParam("value"); 
                } 
            }); 
            newComponent.set("v.name", fieldPath); 
            facet.push(newComponent); 
        } 
    } 
} 
})

What is wrong with this code?

1) You are potentially making a request just to fetch one simple leaf component.

2) The component has to be sent and cached somewhere, another layer of complexity.

3) It makes predictability and unit/functional testing much more harder let alone performance testing.

4) It breaks the rendering "fiber": You are losing your parent chain (forget about sending events up), you are rendering in the next tick (which has many bad perf and UI rendering side effects)

5) We are adding some crazy programmatic event handling which is much harder to read than a simple handler in the markup.

6) Dependency calculation becomes the insanity we are in right now in Aura.

Dynamic component creation should only be used in cases where you are loading a completely big, different, disconnected tree.

So the question is: Why would you want to lazy-load or dynamically create a very simple leaf component?

And the answer for 99% of the cases is for no good reason.

Does webpack route splitting sound familiar? Thats a common pattern in the industry to lazy load or preload components. But you render the whole subtree based on the route! Everything else is completely predictable down the tree.

Are there other valid use-cases? Absolutely, but 99% of the use cases fall into the declarative predictable category, rather than the dynamic craziness.

And thats why in LWC in the platform we don't allow you to shoot yourself in the foot creating small tiny components, and once we do, we will give you a water pistol first :), which means we will make it as predictable, restricted and side-effect free as possible.

Once we do allow it it will be very well documented and we will make sure we can still preserve as much as possible the invariants described above.

8
  • Thanks Diego for the confirmation. Are you talking about webpacks which is used to bundle resources?? And lazy loading means dynamic importing. But is it possible to import template of component into another component? Commented Dec 28, 2018 at 8:34
  • 4
    It is not the matter of use-cases. If you insist that "LWC is Web Components", it should be manipulated like usual DOM elements using DOM API, including dynamic element creation. If you close the way to do it, it also gives way chances of ecosystem in the Web to be utilized in LWC.
    – stomita
    Commented Jan 24, 2019 at 3:52
  • 2
    To answer all questions above: There is no way on the platform as of spring release to dynamically create components for the reasons mentioned above. We will be introducing ways to do this in the future.
    – Diego
    Commented Jan 25, 2019 at 18:43
  • 3
    @diego sorry for highjacking this, but the addValueHandler method is nowhere documented and it caught my interest. War your example rather an Aura Framework Example than a Lightning Components (Aura) Example? Commented Feb 6, 2019 at 13:44
  • 1
    Its implemented and enabled only for some very specific cases internally. We are going to start enabling it for some ISVs shortly.
    – Diego
    Commented Sep 30, 2020 at 11:09
3

Lightning Web Components now supports Dynamic component creation as of Winter '24. You can use the new lwc:component base component and lwc:is directive.

Check the steps below

  1. To instantiate a dynamic component, a component's configuration file must include the lightning__dynamicComponent capability.

     <?xml version="1.0" encoding="UTF-8"?>
     <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
        <apiVersion>59.0</apiVersion>
      <capabilities>
       <capability>lightning__dynamicComponent</capability>
      </capabilities>
     </LightningComponentBundle>
    
  2. To instantiate a component dynamically, use the lwc:component managed element with the lwc:is directive in a component's HTML file.

    <template>
    <div class="container">
      <lwc:component lwc:is={componentConstructor}></lwc:component>
    </div>
    </template>
    
  3. In the component's JavaScript file, import the custom element using the import() dynamic import syntax.

    import { LightningElement } from "lwc";
    
    export default class extends LightningElement {
      componentConstructor;
     // Use connectedCallback() on the dynamic component
     // to signal when it's attached to the DOM
    connectedCallback() {
        import("c/concreteComponent")
        .then(({ default: ctor }) => (this.componentConstructor = ctor))
       .catch((err) => console.log("Error importing component"));
      }
     }
    
2

LWC supports these approaches for dynamic components:

  • Create <if:true/false> branches in a template.
  • Define multiple HTML templates in your component and use a custom render() method that can switch the template based on custom logic or conditions.
  • Compose components using slots.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .