Function Component
Markup does not ship with a dedicated component API. Components are simply functions that return a HTMLTemplate
instance.
const MyButton = () => {
return html` <button type="button">click me</button> `
}
It is totally up to you what these functions can do or look like. From the example above, you can simply render your component using the render
method.
MyButton().render(document.body)
Inputs (Props)
Since its functions, you can take arguments and inject them directly into the template with proper defaults handling.
const Button = ({ content = '', disabled = false, type = 'button' }) => {
return html` <button type="${type}" disabled="${disabled}">
${content}
</button>`
}
Templates can take raw values or functions that returns some value which can be a state
or simply a dynamic value
, in that case, you can have your input type definition use the StateGetter
type.
enum MyButtonType {
Button = 'button',
Reset = 'reset',
Submit = 'submit',
}
interface MyButtonProps {
content: unknown
disabled: boolean | StateGetter<boolean>
type: MyButtonType | StateGetter<MyButtonType>
}
The StateGetter
allows you to communicate that your component takes function values as input which makes it easier to work with states.
Lifecycles
You can take advantage of both effect and html
lifecycles to react to things like component mounted, unmounted, and updates to do everything you need.
const ChatMessages = () => {
const [messages, updateMessages] = state([])
onUpdate(() => {
// todo: scroll to the bottom to show latest msg
})
const onMount = () => {
const controller = new AbortController();
const signal = controller.signal;
fetch('...', { signal })
.then((res) => {
if(!res.ok) throw new Error(res.statusText)
return res.json()
})
.then((res) => updateMessages(res.messages))
.catch(console.error);
// return a function to be called on unmount
// where you can perform any clean ups
return () => {
controller.abort();
}
}
return html`
<ul>
${repeat(messages, msg => html`<li>${msg}</li>
</ul>
`)}
.onMount(onMount)
.onUpdate(onUpdate)
}
Markup template has powerful lifecycles and because a function is called once and with power of reactivity, you can encapsulate everything inside the function leaving everything to Markup to manage.
edit this doc