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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs