@@ -2200,6 +2200,97 @@ test.describe("single-fetch", () => {
22002200 ) . toBe ( true ) ;
22012201 } ) ;
22022202
2203+ test ( "allows reused routes to opt out via shouldRevalidate (w/only clientLoader)" , async ( {
2204+ page,
2205+ } ) => {
2206+ let fixture = await createFixture ( {
2207+ files : {
2208+ ...files ,
2209+ "app/routes/_index.tsx" : js `
2210+ import { Link } from "react-router";
2211+ export default function Component() {
2212+ return <Link to="/parent/a">Go to /parent/a</Link>;
2213+ }
2214+ ` ,
2215+ "app/routes/parent.tsx" : js `
2216+ import { Link, Outlet, useLoaderData } from "react-router";
2217+ let count = 0;
2218+ export function clientLoader({ request }) {
2219+ return { count: ++count };
2220+ }
2221+ export function shouldRevalidate() {
2222+ return false;
2223+ }
2224+ export default function Component() {
2225+ return (
2226+ <>
2227+ <p id="parent">Parent Count: {useLoaderData().count}</p>
2228+ <Link to="/parent/a">Go to /parent/a</Link>
2229+ <Link to="/parent/b">Go to /parent/b</Link>
2230+ <Outlet/>
2231+ </>
2232+ );
2233+ }
2234+ ` ,
2235+ "app/routes/parent.a.tsx" : js `
2236+ import { useLoaderData } from "react-router";
2237+ let count = 0;
2238+ export function loader({ request }) {
2239+ return { count: ++count };
2240+ }
2241+ export default function Component() {
2242+ return <p id="a">A Count: {useLoaderData().count}</p>;
2243+ }
2244+ ` ,
2245+ "app/routes/parent.b.tsx" : js `
2246+ import { useLoaderData } from "react-router";
2247+ let count = 0;
2248+ export function loader({ request }) {
2249+ return { count: ++count };
2250+ }
2251+ export default function Component() {
2252+ return <p id="b">B Count: {useLoaderData().count}</p>;
2253+ }
2254+ ` ,
2255+ } ,
2256+ } ) ;
2257+ let appFixture = await createAppFixture ( fixture ) ;
2258+ let app = new PlaywrightFixture ( appFixture , page ) ;
2259+
2260+ let urls : string [ ] = [ ] ;
2261+ page . on ( "request" , ( req ) => {
2262+ if ( req . url ( ) . includes ( ".data" ) ) {
2263+ urls . push ( req . url ( ) ) ;
2264+ }
2265+ } ) ;
2266+
2267+ await app . goto ( "/" ) ;
2268+
2269+ await app . clickLink ( "/parent/a" ) ;
2270+ await page . waitForSelector ( "#a" ) ;
2271+ expect ( await app . getHtml ( "#parent" ) ) . toContain ( "Parent Count: 1" ) ;
2272+ expect ( await app . getHtml ( "#a" ) ) . toContain ( "A Count: 1" ) ;
2273+ expect ( urls . length ) . toBe ( 1 ) ;
2274+ // Client loader triggers 2 requests on the first navigation
2275+ expect ( urls [ 0 ] . endsWith ( "/parent/a.data" ) ) . toBe ( true ) ;
2276+ urls = [ ] ;
2277+
2278+ await app . clickLink ( "/parent/b" ) ;
2279+ await page . waitForSelector ( "#b" ) ;
2280+ expect ( await app . getHtml ( "#parent" ) ) . toContain ( "Parent Count: 1" ) ;
2281+ expect ( await app . getHtml ( "#b" ) ) . toContain ( "B Count: 1" ) ;
2282+ expect ( urls . length ) . toBe ( 1 ) ;
2283+ expect ( urls [ 0 ] . endsWith ( "/parent/b.data" ) ) . toBe ( true ) ;
2284+ urls = [ ] ;
2285+
2286+ await app . clickLink ( "/parent/a" ) ;
2287+ await page . waitForSelector ( "#a" ) ;
2288+ expect ( await app . getHtml ( "#parent" ) ) . toContain ( "Parent Count: 1" ) ;
2289+ expect ( await app . getHtml ( "#a" ) ) . toContain ( "A Count: 2" ) ;
2290+ expect ( urls . length ) . toBe ( 1 ) ;
2291+ expect ( urls [ 0 ] . endsWith ( "/parent/a.data" ) ) . toBe ( true ) ;
2292+ } ) ;
2293+
22032294 test ( "provides the proper defaultShouldRevalidate value" , async ( {
22042295 page,
22052296 } ) => {
0 commit comments