|
| 1 | +--- |
| 2 | +title: Component API |
| 3 | +sidebar_label: API |
| 4 | +description: Component API |
| 5 | +slug: /api |
| 6 | +--- |
| 7 | + |
| 8 | +# Component API |
| 9 | + |
| 10 | +The whole API provided by stencil can be condensed in a set of decorators, lifecycles hooks and rendering methods. |
| 11 | + |
| 12 | + |
| 13 | +## Decorators |
| 14 | + |
| 15 | +Decorators are a pure compiler-time construction used by stencil to collect all the metadata about a component, the properties, attributes and methods it might expose, the events it might emit or even the associated stylesheets. |
| 16 | +Once all the metadata has been collected, all the decorators are removed from the output, so they don't incur any runtime overhead. |
| 17 | + |
| 18 | +- [@Component()](./component.md) declares a new web component |
| 19 | +- [@Prop()](./properties.md#the-prop-decorator-prop) declares an exposed property/attribute |
| 20 | +- [@State()](./state.md#the-state-decorator-state) declares an internal state of the component |
| 21 | +- [@Watch()](./reactive-data.md#the-watch-decorator-watch) declares a hook that runs when a property or state changes |
| 22 | +- [@Element()](./host-element.md#element-decorator) declares a reference to the host element |
| 23 | +- [@Method()](./methods.md) declares an exposed public method |
| 24 | +- [@Event()](./events.md#event-decorator) declares a DOM event the component might emit |
| 25 | +- [@Listen()](./events.md#listen-decorator) listens for DOM events |
| 26 | + |
| 27 | + |
| 28 | +## Lifecycle hooks |
| 29 | + |
| 30 | +- [connectedCallback()](./component-lifecycle.md#connectedcallback) |
| 31 | +- [disconnectedCallback()](./component-lifecycle.md#disconnectedcallback) |
| 32 | +- [componentWillLoad()](./component-lifecycle.md#componentwillload) |
| 33 | +- [componentDidLoad()](./component-lifecycle.md#componentdidload) |
| 34 | +- [componentShouldUpdate(newValue, oldValue, propName): boolean](./component-lifecycle.md#componentshouldupdate) |
| 35 | +- [componentWillRender()](./component-lifecycle.md#componentwillrender) |
| 36 | +- [componentDidRender()](./component-lifecycle.md#componentdidrender) |
| 37 | +- [componentWillUpdate()](./component-lifecycle.md#componentwillupdate) |
| 38 | +- [componentDidUpdate()](./component-lifecycle.md#componentdidupdate) |
| 39 | +- **[render()](./templating-and-jsx.md)** |
| 40 | + |
| 41 | +## componentOnReady() |
| 42 | + |
| 43 | +This isn't a true "lifecycle" method that would be declared on the component class definition, but instead is a utility method that |
| 44 | +can be used by an implementation consuming your Stencil component to detect when a component has finished its first render cycle. |
| 45 | + |
| 46 | +This method returns a promise which resolves after `componentDidRender()` on the _first_ render cycle. |
| 47 | + |
| 48 | +:::note |
| 49 | +`componentOnReady()` only resolves once per component lifetime. If you need to hook into subsequent render cycle, use |
| 50 | +`componentDidRender()` or `componentDidUpdate()`. |
| 51 | +::: |
| 52 | + |
| 53 | +Executing code after `componentOnReady()` resolves could look something like this: |
| 54 | + |
| 55 | +```ts |
| 56 | +// Get a reference to the element |
| 57 | +const el = document.querySelector('my-component'); |
| 58 | + |
| 59 | +el.componentOnReady().then(() => { |
| 60 | + // Place any code in here you want to execute when the component is ready |
| 61 | + console.log('my-component is ready'); |
| 62 | +}); |
| 63 | +``` |
| 64 | + |
| 65 | +The availability of `componentOnReady()` depends on the component's compiled output type. This method is only available for lazy-loaded |
| 66 | +distribution types ([`dist`](../output-targets/dist.md) and [`www`](../output-targets/www.md)) and, as such, is not available for |
| 67 | +[`dist-custom-elements`](../output-targets/custom-elements.md) output. If you want to simulate the behavior of `componentOnReady()` for non-lazy builds, |
| 68 | +you can implement a helper method to wrap the functionality similar to what the Ionic Framework does [here](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/helpers.ts#L60-L79). |
| 69 | + |
| 70 | +## The `appload` event |
| 71 | + |
| 72 | +In addition to component-specific lifecycle hooks, a special event called `appload` will be emitted when the app and all of its child components have finished loading. You can listen for it on the `window` object. |
| 73 | + |
| 74 | +If you have multiple apps on the same page, you can determine which app emitted the event by checking `event.detail.namespace`. This will be the value of the [namespace config option](../config/01-overview.md#namespace) you've set in your Stencil config. |
| 75 | + |
| 76 | +```tsx |
| 77 | +window.addEventListener('appload', (event) => { |
| 78 | + console.log(event.detail.namespace); |
| 79 | +}); |
| 80 | +``` |
| 81 | + |
| 82 | +## Other |
| 83 | + |
| 84 | +The following primitives can be imported from the `@stencil/core` package and used within the lifecycle of a component: |
| 85 | + |
| 86 | +- [**Host**](./host-element.md): `<Host>`, is a functional component that can be used at the root of the render function to set attributes and event listeners to the host element itself. Refer to the [Host Element](./host-element.md) page for usage info. |
| 87 | + |
| 88 | +- **Fragment**: `<Fragment>`, often used via `<>...</>` syntax, lets you group elements without a wrapper node. |
| 89 | + |
| 90 | + To use this feature, ensure that the following TypeScript compiler options are set: |
| 91 | + - [`jsxFragmentFactory` is set](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory) to "Fragment" |
| 92 | + - [`jsxFactory` is set](https://www.typescriptlang.org/tsconfig#jsxFactory) to "h" |
| 93 | + |
| 94 | + __Type:__ `FunctionalComponent`<br /> |
| 95 | + __Example:__ |
| 96 | + ```tsx |
| 97 | + import { Component, Fragment, h } from '@stencil/core' |
| 98 | + @Component({ |
| 99 | + tag: 'cmp-fragment', |
| 100 | + }) |
| 101 | + export class CmpFragment { |
| 102 | + render() { |
| 103 | + return ( |
| 104 | + <> |
| 105 | + <div>...</div> |
| 106 | + <div>...</div> |
| 107 | + <div>...</div> |
| 108 | + </> |
| 109 | + ); |
| 110 | + } |
| 111 | + } |
| 112 | + ``` |
| 113 | + |
| 114 | +- [**h()**](./templating-and-jsx.md): It's used within the `render()` to turn the JSX into Virtual DOM elements. |
| 115 | + |
| 116 | +- [**readTask()**](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing): Schedules a DOM-read task. The provided callback will be executed in the best moment to perform DOM reads without causing layout thrashing. |
| 117 | + |
| 118 | + __Type:__ `(task: Function) => void` |
| 119 | + |
| 120 | +- [**writeTask()**](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing): Schedules a DOM-write task. The provided callback will be executed in the best moment to perform DOM mutations without causing layout thrashing. |
| 121 | + |
| 122 | + __Type:__ `(task: Function) => void` |
| 123 | + |
| 124 | +- **forceUpdate()**: Schedules a new render of the given instance or element even if no state changed. Notice `forceUpdate()` is not synchronous and might perform the DOM render in the next frame. |
| 125 | + |
| 126 | + __Type:__ `(ref: any) => void`<br /> |
| 127 | + __Example:__ |
| 128 | + ```ts |
| 129 | + import { forceUpdate } from '@stencil/core' |
| 130 | + |
| 131 | + // inside a class component function |
| 132 | + forceUpdate(this); |
| 133 | + ``` |
| 134 | + |
| 135 | +- **getAssetPath()**: Gets the path to local assets. Refer to the [Assets](../guides/assets.md#getassetpath) page for usage info. |
| 136 | + |
| 137 | + __Type:__ `(path: string) => string`<br /> |
| 138 | + __Example:__ |
| 139 | + ```tsx |
| 140 | + import { Component, Prop, getAssetPath, h } from '@stencil/core' |
| 141 | + @Component({ |
| 142 | + tag: 'cmp-asset', |
| 143 | + }) |
| 144 | + export class CmpAsset { |
| 145 | + @Prop() icon: string; |
| 146 | + |
| 147 | + render() { |
| 148 | + return ( |
| 149 | + <img src={getAssetPath(`assets/icons/${this.icon}.png`)} /> |
| 150 | + ); |
| 151 | + } |
| 152 | + } |
| 153 | + ``` |
| 154 | + |
| 155 | +- **setAssetPath()**: Sets the path for Stencil to resolve local assets. Refer to the [Assets](../guides/assets.md#setassetpath) page for usage info. |
| 156 | + |
| 157 | + __Type:__ `(path: string) => string`<br /> |
| 158 | + __Example:__ |
| 159 | + ```ts |
| 160 | + import { setAssetPath } from '@stencil/core'; |
| 161 | + setAssetPath(`{window.location.origin}/`); |
| 162 | + ``` |
| 163 | + |
| 164 | +- **setMode()**: Sets the style mode of a component. Refer to the [Styling](./styling.md#style-modes) page for usage info. |
| 165 | + |
| 166 | + __Type:__ `((elm: HTMLElement) => string | undefined | null) => void`<br /> |
| 167 | + __Example:__ |
| 168 | + ```ts |
| 169 | + import { setMode } from '@stencil/core' |
| 170 | + |
| 171 | + // set mode based on a property |
| 172 | + setMode((el) => el.getAttribute('mode')); |
| 173 | + ``` |
| 174 | + |
| 175 | +- **getMode()**: Get the current style mode of your application. Refer to the [Styling](./styling.md#style-modes) page for usage info. |
| 176 | + |
| 177 | + __Type:__ `(ref: any) => string | undefined`<br /> |
| 178 | + __Example:__ |
| 179 | + ```ts |
| 180 | + import { getMode } from '@stencil/core' |
| 181 | + |
| 182 | + getMode(this); |
| 183 | + ``` |
| 184 | + |
| 185 | +- **getElement()**: Retrieve a Stencil element for a given reference. |
| 186 | + |
| 187 | + __Type:__ `(ref: any) => HTMLStencilElement`<br /> |
| 188 | + __Example:__ |
| 189 | + ```ts |
| 190 | + import { getElement } from '@stencil/core' |
| 191 | + |
| 192 | + const stencilComponent = getElement(document.querySelector('my-cmp')) |
| 193 | + if (stencilComponent) { |
| 194 | + stencilComponent.componentOnReady().then(() => { ... }) |
| 195 | + } |
| 196 | + ``` |
| 197 | + |
0 commit comments