fix: prevent returning the previous route data on route transition (#646)

Co-authored-by: Marco Pasqualetti <marco.pasqualetti@live.com>
This commit is contained in:
Valerio Ageno
2025-03-15 11:42:34 +01:00
committed by GitHub
parent bfd0041c6a
commit 1c45b29ed1
2 changed files with 57 additions and 15 deletions
@@ -7,14 +7,11 @@ import { useServerPayloadData } from '../hooks/useServerPayloadData'
import { RouteMatch } from './RouteMatch'
function createRouteComponent(
routeType: string,
includeChildren: boolean,
): RouteComponent {
function createRouteComponent(routeType: string): RouteComponent {
const RootComponent = (({ children }: RouteProps) => (
<div data-testid={routeType}>
{`${routeType} route`}
{includeChildren ? children : null}
{children}
</div>
)) as RouteComponent
RootComponent.preload = vi.fn()
@@ -22,33 +19,45 @@ function createRouteComponent(
return RootComponent
}
function createLeafRouteComponent(routeType: string): RouteComponent {
const RootComponent = (({ data }: RouteProps) => (
<div data-testid={routeType}>{data ? JSON.stringify(data) : null}</div>
)) as RouteComponent
RootComponent.preload = vi.fn()
RootComponent.displayName = routeType
return RootComponent
}
const root = new Route({
isRoot: true,
component: createRouteComponent('root', true),
component: createRouteComponent('root'),
})
const parent = new Route({
component: createRouteComponent('parent', true),
component: createRouteComponent('parent'),
getParentRoute: (): Route => root,
})
const route = new Route({
component: createRouteComponent('current', false),
component: createLeafRouteComponent('current'),
getParentRoute: (): Route => parent,
})
vi.mock('../hooks/useServerPayloadData', () => ({
useServerPayloadData: vi.fn(),
}))
vi.mocked(useServerPayloadData).mockReturnValue({
data: undefined,
isLoading: false,
})
const useServerPayloadDataMock = vi.mocked(useServerPayloadData)
describe('<RouteMatch />', () => {
afterEach(cleanup)
it('should correctly render nested routes', () => {
useServerPayloadDataMock.mockReturnValue({
data: { some: 'data' },
isLoading: false,
})
render(<RouteMatch route={route} serverInitialData={{}} />)
expect(screen.getByTestId('root')).toMatchInlineSnapshot(
@@ -64,11 +73,38 @@ describe('<RouteMatch />', () => {
<div
data-testid="current"
>
current route
{"some":"data"}
</div>
</div>
</div>
`,
)
})
it('should return null data when while loading', () => {
useServerPayloadDataMock.mockReturnValue({
data: { some: 'data' },
isLoading: true,
})
render(<RouteMatch route={route} serverInitialData={{}} />)
expect(screen.getByTestId('root')).toMatchInlineSnapshot(
`
<div
data-testid="root"
>
root route
<div
data-testid="parent"
>
parent route
<div
data-testid="current"
/>
</div>
</div>
`,
)
})
})
@@ -24,10 +24,16 @@ export const RouteMatch = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
const routes = useMemo(() => loadParentComponents(route), [route.id])
const routeData = isLoading ? null : data
return (
<TraverseRootComponents routes={routes} data={data} isLoading={isLoading}>
<TraverseRootComponents
routes={routes}
data={routeData}
isLoading={isLoading}
>
<Suspense>
<route.component data={data} isLoading={isLoading} />
<route.component data={routeData} isLoading={isLoading} />
</Suspense>
</TraverseRootComponents>
)