Fetchers
Fetchers are data fetching components. They are components that render view and fetch data for necessary operations. They're reusable and composable.
You can even fetch html string from servers just like htmx and render it using koras.jsx with ease.
Quick demo
- A working example of fetcher
const Users = async () => {
const response = await fetch("https://randomuser.me/api?results=30");
const users = await response.json();
return `
<div id="users" data-replace="#list">
<h1 class="text-3xl">User list</h1>
<ul class="list" id="list">
${users.results.map((user) => {
return `
<li class="item">
<img src="${user.picture.medium}">
<p class="name">${user.name.first}</p>
</li>
`;
})}
</ul>
<button
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mb-5"
onClick="$render(Users)">Load more users...</button>
</div>
`;
};- Playground
- Data fetching component with an arrow function
const Users = (props) => {
return `
<div id="users">
<ul id="#componentId" data-prepend="#componentId">
<li>Item 1</li>
</ul>
<!-- the rest of the component -->
</div>
`;
};- Data fetching component with a native function
function Users(props) {
return `
<div id="users">
<ul id="#componentId" data-prepend="#componentId">
<li>Item 1</li>
</ul>
// the rest of the component
</div>
`;
}Content placement attributes
There are six attributes and you have to use one of them whenever you use a data fetching component or place some elements in another. They are:
- data-replace
<ul id="componentId" data-replace="#componentId">
<li>Item 1</li>
</ul>data-replace="#componentId" means an updated version is set to replace the element with id #componentId. data-replace should be added to a data fetching component to replace an element with an updated version.
- data-append
<ul id="componentId" data-append="#componentId">
<li>Item 1</li>
</ul>data-append="#componentId" means more items should be appended to the element with id #componentId. data-append should be added to a data fetching component to append more items.
- data-prepend
<ul id="#componentId" data-prepend="#componentId">
<li>Item 1</li>
</ul>data-prepend="#componentId" means more items should be prepended to an element with id #componentId. data-prepend should be added to a data fetching component to prepend more items.
- data-before
<ul id="#componentId" data-before="#targetComponentId">
<li>Item 1</li>
</ul>data-before="#componentId" is used to insert a component before another component.
- data-after
<ul id="#componentId" data-after="#targetComponentId">
<li>Item 1</li>
</ul>data-after="#componentId" is used to insert a component after another component.
- data-fallback
<ul id="#componentId" data-fallback="fetching...">
<li>Item 1</li>
</ul>or
function Loading(targetId) {
//do something
return "fetching";
}
$register(Loading);Now, use the component as a fallback.
<ul id="#componentId" data-fallback="Loading">
<li>Item 1</li>
</ul>data-fallback="ComponentOrText" is used to set a fallback text or component for a Fetcher while fetching data. If you don't add data-fallback to a Fetcher, it uses loading... by default.
INFO
Extra: We also have data-defer to prevent a component from running on the server.
Calling a fetcher
- Use a fetcher as a component
Without props
<Users />Or
$render(Users);With props
//Dynamically
<Users users=${users} />
or
$render(Users, ${users})
//Statically
<Users users="[{}, {}, {}]" />
or
$render(Users, [{}, {}, {}])
// Use as as event handler
<button onClick="$render(Users, ${users}">
Load users
</button>Inserting a component relative to another component
In this case, fetcher attributes data-after or data-before must be used to insert component before or after another component.
function InsertionTest() {
return `
<div id="insertion-test" data-after="#counter">
It works;
</div>
`;
}
const Counter = (count = 0) => {
return `
<div id="counter">
<div>${count}</div>
<button
onClick="$render(Counter, ${count + 1})"
style="height:30px; width:50px">Increase
</button>
<button
onClick="$render(InsertionTest)">Before
</button>
</div>
`;
};InsertionTest component will be inserted after Counter component.