Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/solid-router/src/Matches.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
): Solid.Accessor<
false | Expand<ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']>
> => {
const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts

return Solid.createMemo(() => {
const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts

router.stores.matchRouteReactivity.state
return router.matchRoute(rest as any, {
pending,
Expand Down Expand Up @@ -185,19 +185,19 @@ export function MatchRoute<
>(props: MakeMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): any {
const matchRoute = useMatchRoute()
const params = matchRoute(props as any)
const child = props.children

const renderedChild = () => {
const renderedChild = Solid.createMemo(() => {
const matchedParams = params()
const child = props.children

if (typeof child === 'function') {
return (child as any)(matchedParams)
}

return matchedParams ? child : null
}
})

return renderedChild()
return <>{renderedChild()}</>
}

export interface UseMatchesBaseOptions<TRouter extends AnyRouter, TSelected> {
Expand Down
84 changes: 83 additions & 1 deletion packages/solid-router/tests/Matches.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { afterEach, describe, expect, test } from 'vitest'
import { createSignal } from 'solid-js'
import {
cleanup,
fireEvent,
Expand All @@ -9,6 +10,7 @@ import {
import { createMemoryHistory } from '@tanstack/history'
import {
Link,
MatchRoute,
Outlet,
RouterProvider,
createRootRoute,
Expand Down Expand Up @@ -112,6 +114,8 @@ const defaultRouter = createRouter({

type DefaultRouter = typeof defaultRouter

afterEach(() => cleanup())

test('when filtering useMatches by loaderData', async () => {
render(() => <RouterProvider router={defaultRouter} />)

Expand Down Expand Up @@ -150,6 +154,85 @@ test('should show pendingComponent of root route', async () => {
expect(await rendered.findByTestId('root-content')).toBeInTheDocument()
})

test('MatchRoute updates for navigation and reactive params changes', async () => {
function Layout() {
const [postId, setPostId] = createSignal('123')

return (
<div>
<button onClick={() => setPostId('456')}>Change Match Params</button>
<MatchRoute to="/posts/$postId" params={{ postId: postId() }}>
{(match) => (
<span data-testid="function-match">
{match ? match.postId : 'no-match'}
</span>
)}
</MatchRoute>
<MatchRoute to="/posts/$postId" params={{ postId: postId() }}>
<span data-testid="plain-match">plain-match</span>
</MatchRoute>
<Outlet />
</div>
)
}

const rootRoute = createRootRoute({
component: Layout,
})

const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: () => null,
})

const postsRoute = createRoute({
getParentRoute: () => rootRoute,
path: 'posts/$postId',
component: () => null,
})

const router = createRouter({
routeTree: rootRoute.addChildren([indexRoute, postsRoute]),
history: createMemoryHistory({ initialEntries: ['/'] }),
})

render(() => <RouterProvider router={router} />)

await waitFor(() => {
expect(screen.getByTestId('function-match')).toHaveTextContent('no-match')
expect(screen.queryByTestId('plain-match')).not.toBeInTheDocument()
})

router.history.push('/posts/123')

await waitFor(() => {
expect(screen.getByTestId('function-match')).toHaveTextContent('123')
expect(screen.getByTestId('plain-match')).toBeInTheDocument()
})

fireEvent.click(screen.getByRole('button', { name: 'Change Match Params' }))

await waitFor(() => {
expect(screen.getByTestId('function-match')).toHaveTextContent('no-match')
expect(screen.queryByTestId('plain-match')).not.toBeInTheDocument()
})

router.history.push('/posts/456')

await waitFor(() => {
expect(screen.getByTestId('function-match')).toHaveTextContent('456')
expect(screen.getByTestId('plain-match')).toBeInTheDocument()
})

router.history.push('/')

await waitFor(() => {
expect(screen.getByTestId('function-match')).toHaveTextContent('no-match')
expect(screen.queryByTestId('plain-match')).not.toBeInTheDocument()
})
})

describe('matching on different param types', () => {
const testCases = [
{
Expand Down Expand Up @@ -308,7 +391,6 @@ describe('matching on different param types', () => {
},
]

afterEach(() => cleanup())
test.each(testCases)(
'$name',
async ({ name, path, params, matchParams, nav }) => {
Expand Down
Loading