| section | api |
|---|---|
| title | createRouteData |
| order | 8 |
| subsection | Data |
| active | true |
import { createRouteData } from "solid-start";
function getStudents() {
return [];
}
// ---cut---
const data = createRouteData(getStudents);createRouteData is a primitive for managing async data fetching. It is a light wrapper over createResource that is router aware so it can handle data refetching. The simplest way to use it is to fetch data from an API.
import { createRouteData } from "solid-start";
export function routeData() {
return createRouteData(async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
});
}Often though we want to be able to set a key for our routeData both to act as a parameter and to allow easy invalidation. The fetcher function does not reactively track, so you must use this option if you wish the route data to update. A "falsy" value turns off data fetching.
import { createRouteData, RouteDataArgs } from "solid-start";
export function routeData({ params } : RouteDataArgs) {
return createRouteData(
async key => {
const response = await fetch(`https://hogwarts.deno.dev/${key[0]}/${key[1]}`);
return (await response.json());
},
{ key: () => ["students", params.id] }
);
}The array returned by the key function can track signals and automatically refetch data when the key changes. One use case for this is refetching data based on when a query param changes (since query param changes don't actually register as a changed route). Consider the following example which implements basic pagination using an after query param:
import { createRouteData, RouteDataArgs } from "solid-start";
export function routeData({ params, location } : RouteDataArgs) {
return createRouteData(
async ([, after]) => {
const response = await fetch(`https://hogwarts.deno.dev/students?after${after}`);
return (await response.json());
},
{ key: () => ["students", location.query['after']] }
);
}createRouteData uses a Solid Store under the hood to store its data. This means that when data is refetched it attempts to diff the data to trigger only the finest-grained updates. By default, it is configured to key data to id. If your backend uses a different field you can set it:
import { createRouteData } from "solid-start";
export function routeData() {
return createRouteData(
async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
},
{
reconcileOptions: {
key: "_id"
}
}
);
}Call createRouteData().
function getStudents() {
return [];
}
// ---cut---
import { createRouteData } from "solid-start";
export function routeData() {
const data = createRouteData(getStudents);
data() // null, data is not yet loaded, triggers Suspense
data.loading // true, data is loading
data.latest // null, data is not yet loaded
}key(string | Array, default: true): Parameters for the route data to key by. A falsy value prevents fetching.initialValue(unknown, defaultundefined): Initial value of the routeData.deferStream(boolean, defaultfalse): Prevent streaming render from flushing until complete.reconcileOptions:key(string, default"id"): The property to use as a key for data diffing.merge(boolean, defaultfalse): When true diff deep merges unrecognized values instead of replacing them.
A Solid Resource. An accessor that returns the data loaded by the fetcher. The accessor additionally has these reactive properties:
state("unresolved" | "pending" | "ready" | "refreshing" | "errored"): Current state of the route data.loading(boolean): Indicates if it is loading.error(unknown): Contains the error if it is currently errored.latest(unknown): A way of reading the current value without triggeringSuspense.