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.
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.
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.
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
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>
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>
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"));
}
}
LWC supports these approaches for dynamic components:
<if:true/false>
branches in a template.render()
method that can switch the template based on custom logic or conditions.