Is there a way to have 'redirect' ALWAYS hard-load a page?
Answered
decorum posted this in #help-forum
decorumOP
I have an app where there is always a SearchBar present in the AppBar of the Root Layout.
Whenever someone fills out the form associated with the SearchBar, it triggers a Server Action that parses the form into Search Params (Query Params) and then calls
This works great! On every other page...
However, when trying to submit a search from the
I've tried adding a
Is there a way to enforce that every time I call
Whenever someone fills out the form associated with the SearchBar, it triggers a Server Action that parses the form into Search Params (Query Params) and then calls
redirect('/search?<formatted-and-encoded-search-params>). This works great! On every other page...
However, when trying to submit a search from the
/search page itself, I don't see my loading.tsx file getting triggered and I don't see any indication that a search is being performed until poof the data is changed immediately on the Search Results page.I've tried adding a
template.tsx file to the route, a <Suspense> tag around the Results Table, nothing seems to trigger an indication to the user that data is being fetched on the backend.Is there a way to enforce that every time I call
redirect , even if I'm already at that path, that I hard-load the page?Answered by joulev
Suspense only renders the loading screen for the first "suspension" (sort of like the stale-while-revalidate approach of data fetching).you can add a
key to the Suspense to force the loading screen:import { Suspense } from "react";
import { Search } from "./search";
async function Data({ query }: { query?: string }) {
await new Promise((resolve) => setTimeout(resolve, 2000));
if (!query) return <div>You didn't search for a query</div>;
return <div>You searched for {query}</div>;
}
export default function Page({
searchParams,
}: {
searchParams: Record<string, string | string[] | undefined>;
}) {
const query = Array.isArray(searchParams.query)
? searchParams.query[0]
: searchParams.query;
return (
<>
<Search />
<Suspense fallback={<div>Loading...</div>} key={query}>
<Data query={query} />
</Suspense>
</>
);
}4 Replies
@decorum I have an app where there is always a SearchBar present in the AppBar of the Root Layout.
Whenever someone fills out the form associated with the SearchBar, it triggers a Server Action that parses the form into Search Params (Query Params) and then calls `redirect('/search?<formatted-and-encoded-search-params>)`.
This works great! On _every other_ page...
However, when trying to submit a search from the `/search` page itself, I don't see my `loading.tsx` file getting triggered and I don't see any indication that a search is being performed until _poof_ the data is changed immediately on the Search Results page.
I've tried adding a `template.tsx` file to the route, a `<Suspense>` tag around the Results Table, nothing seems to trigger an indication to the user that data is being fetched on the backend.
Is there a way to enforce that _every time_ I call `redirect` , even if I'm already at that path, that I hard-load the page?
Suspense only renders the loading screen for the first "suspension" (sort of like the stale-while-revalidate approach of data fetching).you can add a
key to the Suspense to force the loading screen:import { Suspense } from "react";
import { Search } from "./search";
async function Data({ query }: { query?: string }) {
await new Promise((resolve) => setTimeout(resolve, 2000));
if (!query) return <div>You didn't search for a query</div>;
return <div>You searched for {query}</div>;
}
export default function Page({
searchParams,
}: {
searchParams: Record<string, string | string[] | undefined>;
}) {
const query = Array.isArray(searchParams.query)
? searchParams.query[0]
: searchParams.query;
return (
<>
<Search />
<Suspense fallback={<div>Loading...</div>} key={query}>
<Data query={query} />
</Suspense>
</>
);
}Answer
decorumOP
I'll give this a shot @joulev
decorumOP
@joulev that worked like a charm! Cheers!
I ended up making a
and I put that at the same level as my
really appreciate the help!
I ended up making a
template.tsx file that basically looks like this:'use client'
import { useSearchParams } from 'next/navigation'
import { ReactNode, Suspense } from 'react'
import Loading from './loading'
export default function Template({ children }: { children: ReactNode }) {
const searchParams = useSearchParams()
return (
<Suspense fallback={<Loading />} key={searchParams.toString()}>
{children}
</Suspense>
)
}and I put that at the same level as my
page.tsx which is doing the data fetching, and it works like a charm!really appreciate the help!
oh, that's really nice. glad to hear it's working