JAVASCRIPT
Syncing State with URL Query Params using useEffect
Learn how to synchronize React component state with URL query parameters. This snippet uses useEffect to read and update the URL, making component state bookmarkable and shareable.
import React, { useState, useEffect, useCallback } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
function useQueryParams() {
const location = useLocation();
const navigate = useNavigate();
const getQueryParam = useCallback((paramName) => {
const params = new URLSearchParams(location.search);
return params.get(paramName);
}, [location.search]);
const setQueryParam = useCallback((paramName, value) => {
const params = new URLSearchParams(location.search);
if (value) {
params.set(paramName, value);
} else {
params.delete(paramName);
}
navigate(`?${params.toString()}`, { replace: true });
}, [location.search, navigate]);
return [getQueryParam, setQueryParam];
}
function ProductFilter() {
const [category, setCategory] = useState('');
const [getQueryParam, setQueryParam] = useQueryParams();
useEffect(() => {
// Initialize state from URL on mount
const urlCategory = getQueryParam('category');
if (urlCategory) {
setCategory(urlCategory);
}
}, [getQueryParam]);
useEffect(() => {
// Update URL when state changes
setQueryParam('category', category);
}, [category, setQueryParam]);
const handleCategoryChange = (e) => {
setCategory(e.target.value);
};
return (
<div>
<h2>Filter Products</h2>
<select value={category} onChange={handleCategoryChange}>
<option value="">All Categories</option>
<option value="electronics">Electronics</option>
<option value="books">Books</option>
<option value="clothing">Clothing</option>
</select>
<p>Current Category: {category || 'None'}</p>
</div>
);
}
export default ProductFilter;
How it works: This snippet demonstrates how to keep a component's internal state synchronized with URL query parameters. It uses a custom `useQueryParams` hook which leverages `useLocation` and `useNavigate` from `react-router-dom` to read and write URL query strings. `useEffect` hooks in the `ProductFilter` component handle initializing the state from the URL on mount and updating the URL whenever the category state changes, ensuring the URL is always reflective of the current filter selection.