Derive
Similar to <For>, Derive allows you to easily create fine-grained reactivity in JSX.
The <Derive> component produces a JSX element that automatically updates whenever the
provided from signal changes.
import { signal, computed, Derive } from "kiru"
function App() {
const name = signal("bob")
const age = signal(42)
const person = computed(() => ({ name: name.value, age: age.value }))
return () => (
<div>
<input bind:value={name} />
<input type="number" bind:value={age} />
<Derive from={person}>
{(person) => (
<div>
{person.name} is {person.age} years old
</div>
)}
</Derive>
{/* You can also use an object as the `from` prop to derive from multiple signals */}
<Derive from={{ name, age }}>
{({ name, age }) => (
<div>
{name} is {age} years old
</div>
)}
</Derive>
</div>
)
}Async Rendering
<Derive /> also supports resources. When deriving from a Resource,
you can use the fallback prop to show content while the data is loading, and the render function
receives an isStale parameter that indicates whether the data is stale (i.e., a new request is in progress).
You can use multiple resources with <Derive />, or mix resources and signals:
import { signal, resource, Derive } from "kiru"
type ProductsResponse = {
products: Array<{
id: number
title: string
}>
}
function Page() {
const search = signal("")
const data = resource(search, async (search, { signal }) => {
const response = await fetch(
`https://dummyjson.com/products/search?q=${search}`,
{ signal }
)
if (!response.ok) throw new Error(response.statusText)
return response.json() as Promise<ProductsResponse>
})
return () => (
<>
<input bind:value={search} />
<Derive from={data} fallback={<div>Loading...</div>}>
{(data, isStale) => (
<div className={isStale ? "opacity-50" : ""}>
<ul>
{data.products.map((product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
</div>
)}
</Derive>
</>
)
}If any entry in the from prop is a resource, you can use the fallback prop. By default, <Derive /> uses
SWR-style behavior where stale data is shown while new data loads. If you never want to show stale content,
you can use the mode prop (accepted values: "swr" | "fallback"), which defaults to "swr". Setting
it to "fallback" will render the fallback whenever the data is stale.