In this post, I will introduce you to a custom React hook, useQueryState
which you can think of as a useState hook with the additional capability of syncing with the query parameters of a URL. This would be very helpful if you'd like to keep the state across page reloads or share the state through the URL.
useQueryState Hook
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
type UseQueryStateReturnType<T> = [T, Dispatch<SetStateAction<T>>];
const useQueryState = <T>(
param: string,
initialValue: T
): UseQueryStateReturnType<T> => {
const [searchParams, setSearchParams] = useSearchParams();
const paramValue = searchParams.get(param);
let parsedValue: T;
if (paramValue !== null) {
parsedValue = JSON.parse(paramValue) as T;
} else {
parsedValue = initialValue;
}
const [value, setValue] = useState<T>(parsedValue);
useEffect(() => {
setSearchParams((prev) => {
if (value !== null && value !== undefined && value !== "") {
prev.set(param, JSON.stringify(value));
} else prev.delete(param);
return prev;
});
}, [value]);
return [value, setValue];
};
export default useQueryState;
Usage
- Import useQueryState hook into your component
import useQueryState from "..../useQueryState";
- Use within your component
const [searchValue, setSearchValue] = useQueryState<string>("param", "");
Parameters
- param (string): The name of the query parameter.
- initialValue (T): The initial value, will be used when the query parameter is not present in the URL.
Return Value
An Array containing two items: current value and a setter function to update that value respectively
Example
import useQueryState from "..../useQueryState";
const Search = () => {
const [searchValue, setSearchValue] = useQueryState<string>("search", "");
return (
<div className="App">
<input
onChange={(e) => setSearchValue(e.target.value)}
value={searchValue}
placeholder="Search"
/>
<p>Search value is: {searchValue}</p>
</div>
);
};
export default Search;
In this example, the searchValue
state is automatically synced with the search
query parameter in the URL.
Demo
See the interactive codesandbox demo:
Working Explanation
The useQueryState
hook utilizes the useSearchParams hook from react-router-dom
to manage URL query parameters. Here's a detailed breakdown of its functionality:
1. Initial State Setup:
- If a query parameter is present in the URL for the specified key, its value is parsed and used as the initial state.
- If the query parameter is not present, the provided initial value is used.
2. State Synchronization:
- Whenever the state changes, the corresponding query parameter in the URL is updated.
- If the state is set to an empty string, null, or undefined, the query parameter is removed from the URL.
3. Stringify and Parsing:
- Since URL query parameters can only store strings, non-string values are stringified before being stored.
- When retrieving the value from the URL, it is parsed back to its original form before being used as the initial state.
Top comments (0)