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)