Illustration of a microphone

Calls with Kent C. Dodds.

You call, I'll answer.

Listen to the podcasts here
Phone sitting on a stool

What's this all about?

The goal of the Call Kent Podcast is to get my answers to your questions. You record your brief question (120 seconds or less) right from your browser. Then I listen to it later and give my response, and through the magic of technology (ffmpeg), our question and answer are stitched together and published to the podcast feed.

I look forward to hearing from you!

Record your call

Calls with Kent C. Dodds Season 5 — 15 episodes

15.How far can nested UI loaders go for UIs with list of components
07:37
Keywords

Outlet, Deeplinking, nested

Description

the UI at https://nothing.tech/products/phone-3 renders a list of "widgets". I would like each of these widgets to have their own loaders to maximise page speed, furthermore I'd be able to "deeplink" a user straight into a widget. But how do I do that when a route can only have one Outlet?

Here's an example with Promise.all. Before:

// routes/dashboard.tsx
export async function loader() {
	const user = await fetch('/api/user').then(r => r.json())
	const projects = await fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	const notifications = await fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())

	return { user, projects, notifications }
}

After:

export async function loader() {
	const userPromise = fetch('/api/user').then(r => r.json())
	const projectsPromise = userPromise.then(user =>
		fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	)
	const notificationsPromise = userPromise.then(user =>
		fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())
	)

	const [user, projects, notifications] = await Promise.all([
		userPromise,
		projectsPromise,
		notificationsPromise,
	])

	return { user, projects, notifications }
}

Kent's notes:

I forgot that defer is now unnecessary, simply return an object from your loader and any properties on that object that are promises will be sent along as deferred data automatically. Learn more from the links below.

How far can nested UI loaders go for UIs with list of components
15.How far can nested UI loaders go for UIs with list of components
07:37
Keywords

Outlet, Deeplinking, nested

Description

the UI at https://nothing.tech/products/phone-3 renders a list of "widgets". I would like each of these widgets to have their own loaders to maximise page speed, furthermore I'd be able to "deeplink" a user straight into a widget. But how do I do that when a route can only have one Outlet?

Here's an example with Promise.all. Before:

// routes/dashboard.tsx
export async function loader() {
	const user = await fetch('/api/user').then(r => r.json())
	const projects = await fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	const notifications = await fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())

	return { user, projects, notifications }
}

After:

export async function loader() {
	const userPromise = fetch('/api/user').then(r => r.json())
	const projectsPromise = userPromise.then(user =>
		fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	)
	const notificationsPromise = userPromise.then(user =>
		fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())
	)

	const [user, projects, notifications] = await Promise.all([
		userPromise,
		projectsPromise,
		notificationsPromise,
	])

	return { user, projects, notifications }
}

Kent's notes:

I forgot that defer is now unnecessary, simply return an object from your loader and any properties on that object that are promises will be sent along as deferred data automatically. Learn more from the links below.

How far can nested UI loaders go for UIs with list of components
15.How far can nested UI loaders go for UIs with list of components
07:37
Keywords

Outlet, Deeplinking, nested

Description

the UI at https://nothing.tech/products/phone-3 renders a list of "widgets". I would like each of these widgets to have their own loaders to maximise page speed, furthermore I'd be able to "deeplink" a user straight into a widget. But how do I do that when a route can only have one Outlet?

Here's an example with Promise.all. Before:

// routes/dashboard.tsx
export async function loader() {
	const user = await fetch('/api/user').then(r => r.json())
	const projects = await fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	const notifications = await fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())

	return { user, projects, notifications }
}

After:

export async function loader() {
	const userPromise = fetch('/api/user').then(r => r.json())
	const projectsPromise = userPromise.then(user =>
		fetch(`/api/projects?userId=${user.id}`).then(r => r.json())
	)
	const notificationsPromise = userPromise.then(user =>
		fetch(`/api/notifications?userId=${user.id}`).then(r => r.json())
	)

	const [user, projects, notifications] = await Promise.all([
		userPromise,
		projectsPromise,
		notificationsPromise,
	])

	return { user, projects, notifications }
}

Kent's notes:

I forgot that defer is now unnecessary, simply return an object from your loader and any properties on that object that are promises will be sent along as deferred data automatically. Learn more from the links below.

How far can nested UI loaders go for UIs with list of components

Looking for more content?

Have a look at these articles.

See the full blog