1

This logic is about filtering houses based on filters (such as purpose, price etc) when I change the filters nothing happens (no url change) or no error on console. It looks like data is not being passed to searchProperties.

I am unable to find any solution.

Note: Ignore comments.

import classes from "./FilterProperties.module.css";

import { useState } from "react";
import { filterData, getFilterValues } from "../../lib/filterData";
import {
  useLocation,useSearchParams, useNavigate} from "react-router-dom";

import DropDown from "./DropDown";

const FilterProperties = () => {
  const location = useLocation();
  const [filters, setFilters] = useState(filterData);
  const [searchParams, setSearchParams] = useSearchParams();
  const navigate = useNavigate();

  const searchProperties = (filterValues) => {
    const path = location.pathname;
    console.log(path);
    const query = searchParams.get("query");
    console.log(query); // undefined

    const values = getFilterValues(filterValues); // error
    // console.log(values);
    values.forEach((item) => {
      setSearchParams[item.name] = item.value;
    });

    navigate({ pathname: path, query });
  };

  return (
    <div className={classes.item}>
      {filters.map((filter) => (
        <DropDown
          key={filter.queryName}
          placeholder={filter.placeholder}
          filter={filter}
          onChange={(e) => {
            searchProperties({ [filter.queryName]: e.target.value });
          }}
        />
      ))}
    </div>
  );
};

export default FilterProperties;
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Daksh Shah
  • 13
  • 3
  • Are you trying to pass `query` to the next component rendered on the `path` path? Does this help answer your question? https://stackoverflow.com/a/59701168/8690857 – Drew Reese Aug 17 '22 at 17:04
  • After looking over the code a second time it seems you are just trying to update the queryString. Is this correct? Can you walk us through the code, what you are expecting the behavior to be? – Drew Reese Aug 17 '22 at 17:26
  • @DrewReese thanks for such quick response as I mentioned I am new to this really struggling to grasp some concepts of routing. But you can take a minute to watch this youtube.com/watch?v=y47gYvXchXM at 1:29:00 I am doing same thing with different UI(building my own components) and not using next js router , using react router unlike in this video – Daksh Shah – Daksh Shah Aug 17 '22 at 17:27
  • @DrewReese yes I am trying to update query string. – Daksh Shah Aug 17 '22 at 17:30
  • I'll take a look at the video when I can, In the meantime what part of the queryString are you trying to update? Just the `query` query parameter? Or something else? Can you provide an example expected queryString/value you are expecting to see? – Drew Reese Aug 17 '22 at 17:36
  • @DrewReese Thanks for concern. Actually I think I know what is happening I will try to fix it if I am unable to I will let you know everything in detail. Thanks – Daksh Shah Aug 17 '22 at 17:40
  • @DrewReese In the clip at 1:29:00 you will see the link updates on changing the filters in video guy is using next js router, I want to do it using React-Router. I checked the data I am getting every thing correctly even when I change filters I get unique value in console. So the only help I need is updating link. How it is done is it using thunk or something. In the video guy used getStaticprop but I am not using next js suggest me solution. Thanks – Daksh Shah Aug 17 '22 at 22:53
  • QueryString `${baseUrl}/properties/list?locationExternalIDs=${locationExternalIDs}&purpose=${purpose}&categoryExternalID=${categoryExternalID}&bathsMin=${bathsMin}&rentFrequency=${rentFrequency}&priceMin=${minPrice}&priceMax=${maxPrice}&roomsMin=${roomsMin}&sort=${sort}&areaMax=${areaMax}` – Daksh Shah Aug 17 '22 at 22:56
  • this changes based on selection of filters – Daksh Shah Aug 17 '22 at 22:57

1 Answers1

0

It seems you are misusing the setSearchParams function. The useSearchParams hook returns a URLSearchParams object and a setSearchParams function that works similarly to the navigate function but only updates the search part of the URL. The basic gist is that you only need to iterate over the filter key-value pairs, update the searchParams object, and then issue the imperative navigation with the updated query parameters.

Example:

...
const [searchParams, setSearchParams] = useSearchParams();
...

const searchProperties = (filterValues) => {
  const values = getFilterValues(filterValues); // *

  values.forEach(({ name, value }) => {
    searchParams.set(name, value); // <-- set query parameter value
  });

  setSearchParams(searchParams); // <-- update query params
};

* Note: I am assuming that getFilterValues(filterValues) functions and returns all the filter key-value pairs the UI is working with.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • @DakshShah It seems you have *heavily* coupled your data shape to the UI implementation. Here's a workaround that explicitly looks at the dropdown/filterData's `queryName` and applies additional logic to split the select input's value into the min/max components and set the query parameter accordingly. https://codesandbox.io/s/react-router-function-not-getting-props-forked-x75xd9 You can reverse the logic to compute a `minMaxPrice` select value from the query parameters if necessary. – Drew Reese Aug 21 '22 at 22:59
  • Okay I see and I have another question now I want to convert state of same logic into redux store using toolkit. So 1).I use local data to display data to filter box using filterData. 2).Then I use again use filter to set the url params() by looping over. 3).Then I use those params to access data from url. I want to know what will be good approach should I have single slice for (1 and 2) and then 2 slice for 3rd one and a thunk for fetching data is it right approach or am I wrong – Daksh Shah Aug 21 '22 at 23:02
  • @DakshShah Well, React state, regardless where it's located, should be the minimal amount to fully capture and represent the "essence" of state. It's also considered good design to break it down into smaller related "chunks" of state, i.e. state that is often updated together or is otherwise closely related. RTK state slices are one way to logically group related state along with the related actions that operate over *that* state. When it comes to Redux I generally 1 slice/reducer per chunk of state per depth. – Drew Reese Aug 21 '22 at 23:08
  • @DakshShah I see (1) being the state in a slice (or slices), and (2) and (3) being logic in the UI that computes what is called derived from state and props/params/etc... The UI selects the state from redux and applies logic to filter the data for rendering. If you are fetching data, yes, a thunk, or asynchronous action, would be the suggestion. – Drew Reese Aug 21 '22 at 23:10