Using React JS to save the values in URL params

We can set the values in the URL as params for saving it. By using this even after render the saved values will be there.
Created a test-component for Filter section.

By using these filters we are filtering the Products on the basis of Colors, Sizes, Price, Item Name.

const Filter = ({ onFilterChange }) => {
  const location = useLocation();

  const useParams = new URLSearchParams(location.search);
  const initialPrice = useParams.get('price') || '';
  const initialColor = useParams.get('color') || '';
  const initialSize = useParams.get('size') || '';

  const [selectedPriceRange, setSelectedPriceRange] = useState([0, 100]);
  const handleChange = (newValues) => setSelectedPriceRange(newValues);

  const [selectedColors, setSelectedColors] = useState(
    initialColor ? [initialColor] : []
  );
  const [selectedSizes, setSelectedSizes] = useState(
    initialSize ? [initialSize] : []
  );

  const [searchTerm, setSearchTerm] = useState('');
  const [isDropdownVisible, setDropdownVisible] = useState(false);

  const handleColorChange = (color) => {
    const updatedColors = selectedColors.includes(color)
      ? selectedColors.filter((c) => c !== color)
      : [...selectedColors, color];
    setSelectedColors(updatedColors);
    onFilterChange({
      price: selectedPriceRange,
      color: updatedColors,
      size: selectedSizes,
      searchTerm,
    });
  };

  const handleSizeChange = (size) => {
    const updatedSizes = selectedSizes.includes(size)
      ? selectedSizes.filter((s) => s !== size)
      : [...selectedSizes, size];
    setSelectedSizes(updatedSizes);
    onFilterChange({
      price: selectedPriceRange,
      color: selectedColors,
      size: updatedSizes,
      searchTerm,
    });
  };

  useEffect(() => {
    const params = new URLSearchParams();
    if (selectedPriceRange) params.set('price', selectedPriceRange);
    if (selectedColors) params.set('color', selectedColors);
    if (selectedSizes) params.set('size', selectedSizes);
    if (searchTerm) params.set('search', searchTerm);

    window.history.replaceState({}, '', `?${params.toString()}`);
  }, [selectedPriceRange, selectedColors, selectedSizes, searchTerm]);

  const handleFilterChange = () => {

    onFilterChange({
      price: selectedPriceRange,
      color: selectedColors,
      size: selectedSizes,
      searchTerm,
    });
  };

  return (
    <div className="filter-container">
      <Button className='bordered-box bg-gray-500 text-white px-4 py-2 rounded hover:bg-blue-600' onClick={() => setDropdownVisible(!isDropdownVisible)}>
        Filter
      </Button>

      {isDropdownVisible && (
        <div className="filter-dropdown">

          <label className='block text-left font-semibold'>
          <h1 className='text-2xl underline underline-offset-8'>By Item Name/ Item Brand</h1>
            <input className='block border p-2 rounded my-4' type="text" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} />
            <button className='applyFilter' onClick={handleFilterChange}>Filter</button>
          </label>
          

          <label className='block text-left w-3/12 font-semibold ml-12'>
  <h1 className='text-2xl underline underline-offset-8'>By Price</h1>
  <ReactSlider
    className="slider"
    thumbClassName="thumb"
    trackClassName="track"
    defaultValue={[0, 100]}
    ariaLabel={['Lower thumb', 'Upper thumb']}
    ariaValuetext={(state) => `Thumb value ${state.valueNow}`}
    renderThumb={(props, state) => <div {...props}>{state.valueNow}</div>}
    pearling
    minDistance={10}
    onChange={(selectedPriceRange) => handleChange(selectedPriceRange)}
  />
  <div style={{ display: 'flex', justifyContent: 'space-between' }}>
  </div>
  <button className='applyFilter' onClick={handleFilterChange}>
    Filter
  </button>
</label>

          <label className="block text-center w-3/12 font-semibold">
          <h1 className='text-2xl mb-3 text-left underline underline-offset-8'>By Size </h1>
            {["XS", "SM", "LG", "MD", "XXL"].map((size) => (
              <div key={size} className="mb-2 text-left">
                <input className='mr-6 w-4 h-4 text-center' type="checkbox" value={size} checked={selectedSizes.includes(size)} onChange={() => handleSizeChange(size)} />
                <label className='text-center'>{size}</label>
              </div>
            ))}
          </label>

          <label className="block text-center w-3/12 float-right font-semibold">
            <h1 className='text-2xl mb-3 text-left underline underline-offset-8'>By Color</h1>
            {["blue", "black", "brown", "gray", "gold"].map((color) => (
              <div key={color} className='mb-2 text-left'>
                <input className='mr-6 w-7 h-7 rounded-full' type="checkbox" value={color} checked={selectedColors.includes(color)} onChange={() => handleColorChange(color)} />
                <label className='text-center text-xl'>{color}</label>
              </div>
            ))}
          </label>

          
        </div>
      )}
    </div>
  );
};

Here useParams in code const useParams = new URLSearchParams(location.search);
const initialPrice = useParams.get(‘price’) || ”;
is for getting the price values from parameter. And same for setting the values we are using ,
const params = new URLSearchParams();
if (selectedPriceRange) params.set(‘price’, selectedPriceRange);

Leave a comment

Your email address will not be published. Required fields are marked *