Data loading
What's a modern app without some data to power it. SolidStart aims to make it easy to load data from your data sources. It will help you keep your UI updated with your data. For most of your data requirements, you will likely be using the route to decide what data to load.
The URL is the primary way of navigating around your app. SolidStart already has nested routing to help structure your app's UI in a hierarchical way, so that you can share layouts. This nested routing comes with other advantages too.
It allows you to declare what data you need for each part of the route. This is done by exporting routeData
functions from the nested routes. Each route, leaf or layout, comes with the ability to export its own routeData
function that will be managed by the router. Yeah, the router is also the data manager.
Solid has a createResource
primitive that takes an async function and returns a signal from it. It's a great starting place for your data needs. It integrates with Suspense
and ErrorBoundary
to help you manage your lifecycle. Let's take a look at how we can use this to load data from a third party API for our app.
tsx
import { createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js";
export function routeDatafunction routeData(): {
students: Resource<any>;
}
() { const [studentsconst students: Resource<any>
] = createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) createResource<any, unknown>(fetcher: ResourceFetcher<true, any, unknown>, options?: ResourceOptions<any, true> | undefined): ResourceReturn<any, unknown> (+3 overloads)
import createResource
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
(); });
return { students(property) students: Resource<any>
}; }
tsx
import { createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js";
export function routeDatafunction routeData(): {
students: Resource<any>;
}
() { const [studentsconst students: Resource<any>
] = createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) createResource<any, unknown>(fetcher: ResourceFetcher<true, any, unknown>, options?: ResourceOptions<any, true> | undefined): ResourceReturn<any, unknown> (+3 overloads)
import createResource
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
(); });
return { students(property) students: Resource<any>
}; }
Now your component can use the useRouteData
function to access the data that is returned by routeData
.
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
} from "solid-start";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): {
students: Resource<Student[]>;
}
() { const [studentsconst students: Resource<Student[]>
] = createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) createResource<Student[], unknown>(fetcher: ResourceFetcher<true, Student[], unknown>, options?: ResourceOptions<Student[], true> | undefined): ResourceReturn<...> (+3 overloads)
import createResource
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
return { students(property) students: Resource<Student[]>
}; }
export default function Pagefunction Page(): JSX.Element
() { const { studentsconst students: Resource<Student[]>
} = useRouteData(alias) useRouteData<() => {
students: Resource<Student[]>;
}>(): {
students: Resource<Student[]>;
} (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): {
students: Resource<Student[]>;
}
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
} from "solid-start";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): {
students: Resource<Student[]>;
}
() { const [studentsconst students: Resource<Student[]>
] = createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) createResource<Student[], unknown>(fetcher: ResourceFetcher<true, Student[], unknown>, options?: ResourceOptions<Student[], true> | undefined): ResourceReturn<...> (+3 overloads)
import createResource
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
return { students(property) students: Resource<Student[]>
}; }
export default function Pagefunction Page(): JSX.Element
() { const { studentsconst students: Resource<Student[]>
} = useRouteData(alias) useRouteData<() => {
students: Resource<Student[]>;
}>(): {
students: Resource<Student[]>;
} (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): {
students: Resource<Student[]>;
}
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
Caveats:
- The
routeData
function is only called once per route, the first time the user comes to that route. After that, the fine-grained resources that remain alive synchronize with state/url changes to refetch data when needed. If you need to refresh the data, you can use the refetch
function that is returned by createResource
. - The
routeData
function is called before the route is rendered. It doesn't share the same context
as the route. The context tree that is exposed to the routeData
function is anything above the Routes
component. - The component receives exactly what the
routeData
function returns when they call useRouteData
. This means that you can return anything you want from the routeData
function. There is no serialization happening in this relationship. - The
routeData
function will be called both on the server and the client. It's the resources that can avoid refetching if they had serialized their data in the server render. - The server-side render will only wait for the resources to fetch and serialize if the resource signals are accessed under a
Suspense
boundary.
Okay, enough with the rules. We thought createResource
was too low level for most people's needs and did not use the knowledge the router has. So we created createRouteData
. It's a resource creator that is aware of the router and the actions created on the page. It adds the concept of keys to the resource so that they can be granularly refetched using refetchRouteData
.
Here's the same example as above, but using createRouteData
:
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
, createRouteData(alias) function createRouteData<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S>): Resource<T | undefined> (+1 overload)
import createRouteData
} from "solid-start";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { return createRouteData(alias) createRouteData<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createRouteData
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
}
export default function Pagefunction Page(): JSX.Element
() { const studentsconst students: Resource<Student[] | undefined>
= useRouteData(alias) useRouteData<() => Resource<Student[] | undefined>>(): Resource<Student[] | undefined> (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): Resource<Student[] | undefined>
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
, createRouteData(alias) function createRouteData<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S>): Resource<T | undefined> (+1 overload)
import createRouteData
} from "solid-start";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { return createRouteData(alias) createRouteData<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createRouteData
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://hogwarts.deno.dev/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
}
export default function Pagefunction Page(): JSX.Element
() { const studentsconst students: Resource<Student[] | undefined>
= useRouteData(alias) useRouteData<() => Resource<Student[] | undefined>>(): Resource<Student[] | undefined> (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): Resource<Student[] | undefined>
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
Data loading always on the server
The primary advantage of being a full-stack Javascript framework is that its easy to write data loading code that can run both on the server and client. SolidStart gives them superpowers. You might want to write code that only runs on your server but didn't want to create an API route for it.
It could be database access, or internal APIs, etc. It could sit within your functions where you need to use your server. We created createServerData$
for this. It builds upon our other primitives like createRouteData
and server$
to give a generated RPC for your data.
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { return createServerData$(alias) createServerData$<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createServerData$
(() => hogwartsconst hogwarts: {
students: {
list(): Student[];
};
}
.students(property) students: {
list(): Student[];
}
.list(method) list(): Student[]
()); }
export default function Pagefunction Page(): JSX.Element
() { const studentsconst students: Resource<Student[] | undefined>
= useRouteData(alias) useRouteData<() => Resource<Student[] | undefined>>(): Resource<Student[] | undefined> (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): Resource<Student[] | undefined>
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { return createServerData$(alias) createServerData$<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createServerData$
(() => hogwartsconst hogwarts: {
students: {
list(): Student[];
};
}
.students(property) students: {
list(): Student[];
}
.list(method) list(): Student[]
()); }
export default function Pagefunction Page(): JSX.Element
() { const studentsconst students: Resource<Student[] | undefined>
= useRouteData(alias) useRouteData<() => Resource<Student[] | undefined>>(): Resource<Student[] | undefined> (+1 overload)
import useRouteData
<typeof routeDatafunction routeData(): Resource<Student[] | undefined>
>();
return (
<ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> <Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
each(property) each: false | Student[] | null | undefined
={studentsconst students: () => Student[] | undefined
()}> {(student(parameter) student: Student
) => <li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>{student(parameter) student: Student
.name}</li(property) JSX.HTMLElementTags.li: JSX.LiHTMLAttributes<HTMLLIElement>
>} </Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
> </ul(property) JSX.HTMLElementTags.ul: JSX.HTMLAttributes<HTMLUListElement>
> );
}
Multiple data sources inside a route
You can have multiple data sources inside a route. You can even have multiple data sources for the same resource. This is useful when you have a route that needs to load data from multiple sources.
For example, you might have a route that needs to load data from a database and a third party API. You can use createServerData$
to load data from the database and createRouteData
to load data from the third party API.
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
, createRouteData(alias) function createRouteData<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S>): Resource<T | undefined> (+1 overload)
import createRouteData
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): {
students: Resource<Student[] | undefined>;
localStudents: Resource<never[] | undefined>;
}
() { const studentsconst students: Resource<Student[] | undefined>
= createRouteData(alias) createRouteData<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createRouteData
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://durmstrang.edu/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
const localStudentsconst localStudents: Resource<never[] | undefined>
= createServerData$(alias) createServerData$<never[], true>(fetcher: RouteDataFetcher<true, never[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<never[] | undefined> (+1 overload)
import createServerData$
(() => hogwartsconst hogwarts: {
students: {
list(): never[];
};
}
.students(property) students: {
list(): never[];
}
.list());
return { students(property) students: Resource<Student[] | undefined>
, localStudents(property) localStudents: Resource<never[] | undefined>
}; }
/routes/students.tsx
tsx
import { Forcreates a list elements from a list
it receives a map function as its child that receives a list element and an accessor with the index and returns a JSX-Element; if the list is empty, an optional fallback is returned:
```typescript
<For each={items} fallback={<div>No items</div>}>
{(item, index) => <div data-index={index()}>{item}</div>}
</For>
```
If you have a list with fixed indices and changing values, consider using `<Index>` instead.
(alias) function For<T extends readonly any[], U extends JSX.Element>(props: {
each: T | undefined | null | false;
fallback?: JSX.Element;
children: (item: T[number], index: Accessor<number>) => U;
}): JSX.Element
import For
, Accessor(alias) type Accessor<T> = () => T
import Accessor
, createResourceCreates a resource that wraps a repeated promise in a reactive pattern:
```typescript
// Without source
const [resource, { mutate, refetch }] = createResource(fetcher, options);
// With source
const [resource, { mutate, refetch }] = createResource(source, fetcher, options);
```
(alias) function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R> (+3 overloads)
import createResource
} from "solid-js"; import { useRouteData(alias) function useRouteData<T extends "$">(): ReturnType<StartRoutes[T]["data"]> (+1 overload)
import useRouteData
, createRouteData(alias) function createRouteData<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S>): Resource<T | undefined> (+1 overload)
import createRouteData
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
type Studenttype Student = {
name: string;
house: string;
}
= { name: string; house: string; }
export function routeDatafunction routeData(): {
students: Resource<Student[] | undefined>;
localStudents: Resource<never[] | undefined>;
}
() { const studentsconst students: Resource<Student[] | undefined>
= createRouteData(alias) createRouteData<Student[], true>(fetcher: RouteDataFetcher<true, Student[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<...> (+1 overload)
import createRouteData
(async () => { const response = await fetchfunction fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>
("https://durmstrang.edu/students"); return await response.json(method) Body.json(): Promise<any>
() as Studenttype Student = {
name: string;
house: string;
}
[]; });
const localStudentsconst localStudents: Resource<never[] | undefined>
= createServerData$(alias) createServerData$<never[], true>(fetcher: RouteDataFetcher<true, never[]>, options?: RouteDataOptions<undefined, true> | undefined): Resource<never[] | undefined> (+1 overload)
import createServerData$
(() => hogwartsconst hogwarts: {
students: {
list(): never[];
};
}
.students(property) students: {
list(): never[];
}
.list());
return { students(property) students: Resource<Student[] | undefined>
, localStudents(property) localStudents: Resource<never[] | undefined>
}; }
Understanding the lifecycle
Let's try to understand when the routeData
is called and why you should set up resources (or use our helpers) inside it.
When rendering on the server, for each segment along the requested path, the routeData functions are called, parent-first. For example, for the following route structure:
sh
├── routes
│ ├── [house].tsx
│ ├── [house]
│ │ ├── index.tsx
│ │ ├── students.tsx
│ │ ├── students
│ │ │ ├── index.tsx
│ │ │ ├── year-[year].tsx
│ │ └── staff.tsx
sh
├── routes
│ ├── [house].tsx
│ ├── [house]
│ │ ├── index.tsx
│ │ ├── students.tsx
│ │ ├── students
│ │ │ ├── index.tsx
│ │ │ ├── year-[year].tsx
│ │ └── staff.tsx
When you visit /gryffindor/students
, the following routeData
functions are called, in this order:
/routes/[house].tsx
/routes/[house]/students.tsx
/routes/[house]/students/index.tsx
You can imagine what the router is doing. You don't have to write this code. It's pseudo-code to help you understand what's going on.
tsx
import { useLocation(alias) const useLocation: () => Location<unknown>
import useLocation
, useNavigate(alias) const useNavigate: () => Navigator
import useNavigate
, RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
} from "solid-start"; import {
defaultfunction HouseLayout(props: {
children?: JSX.Element;
}): JSX.Element
as HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getHouseLayoutData(alias) function getHouseLayoutData(args: RouteDataArgs): {}
import getHouseLayoutData
} from './routes/[house]';
import {
defaultfunction StudentsLayout(props: {
children?: JSX.Element;
}): JSX.Element
as StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getStudentsLayoutData(alias) function getStudentsLayoutData(args: RouteDataArgs): {}
import getStudentsLayoutData
} from './routes/[house]/students';
import {
defaultfunction Students(): JSX.Element
as Students(alias) function Students(): JSX.Element
import Students
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getStudentsData(alias) function getStudentsData(args: RouteDataArgs): {}
import getStudentsData
} from './routes/[house]/students/index';
function Routesfunction Routes(): JSX.Element
() { const argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
= { location(property) location: Location<unknown>
: useLocation(alias) useLocation(): Location<unknown>
import useLocation
(), navigate(property) navigate: Navigator
: useNavigate(alias) useNavigate(): Navigator
import useNavigate
(), params(property) params: {
house: string;
}
: { house: 'gryffindor' } }
const houseLayoutDataconst houseLayoutData: {}
= getHouseLayoutData(alias) getHouseLayoutData(args: RouteDataArgs<"$">): {}
import getHouseLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: null } as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
); const studentsLayoutDataconst studentsLayoutData: {}
= getStudentsLayoutData(alias) getStudentsLayoutData(args: RouteDataArgs<"$">): {}
import getStudentsLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: houseLayoutDataconst houseLayoutData: {}
} as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
); const studentsData = getStudentsLayoutData(alias) getStudentsLayoutData(args: RouteDataArgs<"$">): {}
import getStudentsLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: studentsLayoutDataconst studentsLayoutData: {}
} as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
);
return (
<RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: houseLayoutDataconst houseLayoutData: {}
}}> <HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
> <RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: studentsLayoutDataconst studentsLayoutData: {}
}}> <StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
> <RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: studentsData }}> <Students(alias) function Students(): JSX.Element
import Students
/> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> </StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> </HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> );
}
tsx
import { useLocation(alias) const useLocation: () => Location<unknown>
import useLocation
, useNavigate(alias) const useNavigate: () => Navigator
import useNavigate
, RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
} from "solid-start"; import {
defaultfunction HouseLayout(props: {
children?: JSX.Element;
}): JSX.Element
as HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getHouseLayoutData(alias) function getHouseLayoutData(args: RouteDataArgs): {}
import getHouseLayoutData
} from './routes/[house]';
import {
defaultfunction StudentsLayout(props: {
children?: JSX.Element;
}): JSX.Element
as StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getStudentsLayoutData(alias) function getStudentsLayoutData(args: RouteDataArgs): {}
import getStudentsLayoutData
} from './routes/[house]/students';
import {
defaultfunction Students(): JSX.Element
as Students(alias) function Students(): JSX.Element
import Students
, routeDatafunction routeData(args: RouteDataArgs<"$">): {}
as getStudentsData(alias) function getStudentsData(args: RouteDataArgs): {}
import getStudentsData
} from './routes/[house]/students/index';
function Routesfunction Routes(): JSX.Element
() { const argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
= { location(property) location: Location<unknown>
: useLocation(alias) useLocation(): Location<unknown>
import useLocation
(), navigate(property) navigate: Navigator
: useNavigate(alias) useNavigate(): Navigator
import useNavigate
(), params(property) params: {
house: string;
}
: { house: 'gryffindor' } }
const houseLayoutDataconst houseLayoutData: {}
= getHouseLayoutData(alias) getHouseLayoutData(args: RouteDataArgs<"$">): {}
import getHouseLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: null } as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
); const studentsLayoutDataconst studentsLayoutData: {}
= getStudentsLayoutData(alias) getStudentsLayoutData(args: RouteDataArgs<"$">): {}
import getStudentsLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: houseLayoutDataconst houseLayoutData: {}
} as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
); const studentsData = getStudentsLayoutData(alias) getStudentsLayoutData(args: RouteDataArgs<"$">): {}
import getStudentsLayoutData
({ ...argsconst args: {
location: Location<unknown>;
navigate: Navigator;
params: {
house: string;
};
}
, data: studentsLayoutDataconst studentsLayoutData: {}
} as RouteDataArgs(alias) type RouteDataArgs<T extends "$" = "$"> = {
data: StartRoutes[T]["data"];
params: RouteParams<StartRoutes[T]["params"]>;
location: Location;
navigate: Navigator;
}
import RouteDataArgs
);
return (
<RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: houseLayoutDataconst houseLayoutData: {}
}}> <HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
> <RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: studentsLayoutDataconst studentsLayoutData: {}
}}> <StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
> <RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
value(property) value: {
data: any;
}
={{ data: studentsData }}> <Students(alias) function Students(): JSX.Element
import Students
/> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> </StudentsLayout(alias) function StudentsLayout(props: ParentProps): JSX.Element
import StudentsLayout
> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> </HouseLayout(alias) function HouseLayout(props: ParentProps): JSX.Element
import HouseLayout
> </RouteContextconst RouteContext: Context<{
data: any;
}>
.Provider(property) Context<{ data: any; }>.Provider: ContextProviderComponent<{
data: any;
}>
> );
}