Component
To create a component:
- Create a subclass that inherits from
Component
class and definebuild
method. - Instantiate the subclass
To display the component in UI, use mountComponent
function.
Here is an example of Counter component. The value of count starts with 0
. When the Click Me
button is clicked, the value of count increases by 1
and the new value is displayed in the UI.
counter.js
:
import Component from './node_modules/@xylem-js/xylem-js/dom/Component.js'; import createStore from './node_modules/@xylem-js/xylem-js/core/createStore.js'; import mountComponent from './node_modules/@xylem-js/xylem-js/dom/mountComponent.js'; import parseHTML from './node_modules/@xylem-js/xylem-js/dom/parseHTML.js'; class Counter extends Component { build() { const count$ = createStore(0); return parseHTML([ '<div>', [ 'Count: ', count$, ], '</div>', '<div>', [ '<button>', { '@click': () => count$._(count$._() + 1), }, [ 'Click Me', ], '</button>', ], '</div>', ]); } } mountComponent(new Counter(), document.getElementById('app-container'));
JSX version:
counter-jsx.tsx
:
import Component from './node_modules/@xylem-js/xylem-js/dom/Component.js'; import mountComponent from './node_modules/@xylem-js/xylem-js/dom/mountComponent.js'; class Counter extends Component { build() { const count$ = createStore(0); return <> <div> Current count: {} { count$ } </div> <div> <button on:click={() => count$._(count$._() + 1)} > Click </button> </div> </>; } } mountComponent(new Counter(), document.getElementById('app-container')!);
Lifecycle events of component
Component has following lifecycle events:
- afterSetup
- afterAttachToDom
- beforeDetachFromDom
The lifecycle events are available as property of the component with the same name.
afterSetup
This is called after virtual DOM tree is created, before DOM nodes are available. This is useful to modify components like modifying class attribute. However, it is rarely necessary.
For Server Side Rendered component, this is called in both server side and client side.
afterAttachToDom
This is called after DOM tree is attached to the document. The subscribers are called immediately, so any changes made to the DOM nodes is immediately reflected without flash of previous state.
This is useful for asynchronous operation like setTimeout()
, setInterval()
, fetch()
, XMLHttpRequest:send()
etc.
For Server Side Rendered component, this is not called in server side but during hydration in client side.
beforeDetachFromDom
This is called before DOM tree is removed from the document.
This is useful for cleanup of operation done in afterAttachToDom
like clearTimeout()
, clearInterval()
, AbortController:abort()
, XMLHttpRequest:abort()
etc.
Example
The example below shows Clock component that shows current date-time and update every second. In afterAttachToDom
, setInterval()
is called and in beforeDetachFromDom
, clearInterval()
is called.
clock.js
:
import Component from './node_modules/@xylem-js/xylem-js/dom/Component.js'; import createStore from './node_modules/@xylem-js/xylem-js/core/createStore.js'; import mountComponent from './node_modules/@xylem-js/xylem-js/dom/mountComponent.js'; import parseHTML from './node_modules/@xylem-js/xylem-js/dom/parseHTML.js'; class Clock extends Component { build() { const currentDateTime$ = createStore(''); let intervalID; this.afterAttachToDom.subscribe(() => { currentDateTime$._(new Date() + ''); intervalID = setInterval(() => { currentDateTime$._(new Date() + ''); }, 1000); }); this.beforeDetachFromDom.subscribe(() => { clearInterval(intervalID); }); return parseHTML([ '<div>', [ 'Current date-time: ', currentDateTime$, ], '</div>', ]); } } mountComponent(new Clock(), document.getElementById('app-container'));