useSearchParams
useSearchParams
gives you a read/write pair for the search params in the current location.
ts
const [searchParamsconst searchParams: Params
, setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
();
ts
const [searchParamsconst searchParams: Params
, setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
();
Usage
Rendering based on search params
Search params can be a powerful way of controlling the UI. For example, you can use them to control the sorting of a list of items, or to filter the items based on some criteria. What does this enable? You can share that URL and the other person will be able to see the same UI as you without configuring anything themselves.
It also enables you to use the browser's back/forward buttons to navigate between different states of the UI. To read the current URLSearchParams
, call useSearchParams()
inside a component. The first item in the tuple with be a reactive object with the search params from the current location. You can access them in a listening scope to react to changes.
For example, they can be used in the JSX to customize the UI.
tsx
import { Resource(alias) type Resource<T> = Unresolved | Pending | Ready<T> | Refreshing<T> | Errored
import Resource
} from 'solid-js'; import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
, useRouteData(alias) const useRouteData: <T>() => MaybeReturnType<T>
import useRouteData
} from "solid-start";
export default function Pagefunction Page(): JSX.Element
() { const [searchParamsconst searchParams: Params
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); const dataconst data: Resource<Student[]>
= useRouteData(alias) useRouteData<() => Resource<Student[]>>(): Resource<Student[]>
import useRouteData
<() => Resource(alias) type Resource<T> = Unresolved | Pending | Ready<T> | Refreshing<T> | Errored
import Resource
<Student[]>>(); return (
<div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> <FilteredListfunction FilteredList(props: any): JSX.Element
data(property) data: Student[] | undefined
={dataconst data: () => Student[] | undefined
()} filter(property) filter: string
={searchParamsconst searchParams: Params
.filter} />
</div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> );
}
tsx
import { Resource(alias) type Resource<T> = Unresolved | Pending | Ready<T> | Refreshing<T> | Errored
import Resource
} from 'solid-js'; import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
, useRouteData(alias) const useRouteData: <T>() => MaybeReturnType<T>
import useRouteData
} from "solid-start";
export default function Pagefunction Page(): JSX.Element
() { const [searchParamsconst searchParams: Params
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); const dataconst data: Resource<Student[]>
= useRouteData(alias) useRouteData<() => Resource<Student[]>>(): Resource<Student[]>
import useRouteData
<() => Resource(alias) type Resource<T> = Unresolved | Pending | Ready<T> | Refreshing<T> | Errored
import Resource
<Student[]>>(); return (
<div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> <FilteredListfunction FilteredList(props: any): JSX.Element
data(property) data: Student[] | undefined
={dataconst data: () => Student[] | undefined
()} filter(property) filter: string
={searchParamsconst searchParams: Params
.filter} />
</div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> );
}
Fetching data based on search params
Similar to customizing the UI based on search params, you can also use them to fetch specific data from the server. Imagine a search page. You would want to persist the searched query in the query. if the user comes to the search page with a search param, you can directly show those results.
So, you need the search param as a source for your resources. You can use useSearchParams
to get the search params and use them just like you would any other store value.
routes/search.tsx
tsx
import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { const [searchParamsconst searchParams: Params
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); return createServerData$(alias) createServerData$<Student[], string>(fetcher: RouteDataFetcher<string, Student[]>, options?: RouteDataOptions<undefined, string> | undefined): Resource<...> (+1 overload)
import createServerData$
(async (query(parameter) query: string
) => { return hogwartsconst hogwarts: {
search(query: string): Promise<Student[]>;
}
.search(method) search(query: string): Promise<Student[]>
(query(parameter) query: string
) }, {
key(property) key?: RouteDataSource<string>
: () => searchParamsconst searchParams: Params
.query })
}
routes/search.tsx
tsx
import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
} from "solid-start"; import { createServerData$(alias) const createServerData$: {
<T, S = true>(fetcher: RouteDataFetcher<S, T>, options?: RouteDataOptions<undefined, S> | undefined): Resource<T | undefined>;
<T, S = true>(fetcher: RouteDataFetcher<...>, options: RouteDataOptions<...>): Resource<...>;
}
import createServerData$
} from "solid-start/server";
export function routeDatafunction routeData(): Resource<Student[] | undefined>
() { const [searchParamsconst searchParams: Params
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); return createServerData$(alias) createServerData$<Student[], string>(fetcher: RouteDataFetcher<string, Student[]>, options?: RouteDataOptions<undefined, string> | undefined): Resource<...> (+1 overload)
import createServerData$
(async (query(parameter) query: string
) => { return hogwartsconst hogwarts: {
search(query: string): Promise<Student[]>;
}
.search(method) search(query: string): Promise<Student[]>
(query(parameter) query: string
) }, {
key(property) key?: RouteDataSource<string>
: () => searchParamsconst searchParams: Params
.query })
}
Updating search params from the UI
Now, what's the point of a search page without the ability to change the search query. So let's add a search box to the page. We can use the setSearchParams
function to update the search params. All the instances of useSearchParams
will be updated with the new search params. Your data will refetch and the UI will update.
routes/search.tsx
tsx
import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
} from "solid-start";
export default function SearchBoxfunction SearchBox(): JSX.Element
() { const [searchParamsconst searchParams: Params
, setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); return (
<div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> <input(property) JSX.HTMLElementTags.input: JSX.InputHTMLAttributes<HTMLInputElement>
type(property) JSX.InputHTMLAttributes<HTMLInputElement>.type?: string | undefined
="text" onInput(property) JSX.CustomEventHandlersCamelCase<HTMLInputElement>.onInput?: JSX.EventHandlerUnion<HTMLInputElement, InputEvent> | undefined
={(e(parameter) e: InputEvent & {
currentTarget: HTMLInputElement;
target: Element;
}
) => setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
({ query: e(parameter) e: InputEvent & {
currentTarget: HTMLInputElement;
target: Element;
}
.currentTargetReturns the object whose event listener's callback is currently being invoked.
(property) currentTarget: EventTarget & HTMLInputElement
.valueReturns the value of the data at the cursor's current position.
(property) HTMLInputElement.value: string
})} />
</div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> );
}
routes/search.tsx
tsx
import { useSearchParams(alias) const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void]
import useSearchParams
} from "solid-start";
export default function SearchBoxfunction SearchBox(): JSX.Element
() { const [searchParamsconst searchParams: Params
, setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
] = useSearchParams(alias) useSearchParams<Params>(): [Params, (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void]
import useSearchParams
(); return (
<div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> <input(property) JSX.HTMLElementTags.input: JSX.InputHTMLAttributes<HTMLInputElement>
type(property) JSX.InputHTMLAttributes<HTMLInputElement>.type?: string | undefined
="text" onInput(property) JSX.CustomEventHandlersCamelCase<HTMLInputElement>.onInput?: JSX.EventHandlerUnion<HTMLInputElement, InputEvent> | undefined
={(e(parameter) e: InputEvent & {
currentTarget: HTMLInputElement;
target: Element;
}
) => setSearchParamsconst setSearchParams: (params: SetParams, options?: Partial<NavigateOptions<unknown>> | undefined) => void
({ query: e(parameter) e: InputEvent & {
currentTarget: HTMLInputElement;
target: Element;
}
.currentTargetReturns the object whose event listener's callback is currently being invoked.
(property) currentTarget: EventTarget & HTMLInputElement
.valueReturns the value of the data at the cursor's current position.
(property) HTMLInputElement.value: string
})} />
</div(property) JSX.HTMLElementTags.div: JSX.HTMLAttributes<HTMLDivElement>
> );
}