router icon indicating copy to clipboard operation
router copied to clipboard

feat: type safe useSetSearch

Open gronxb opened this issue 2 years ago • 3 comments

Summary

Inspired by React Router's useSearchParams,

The useNavigate method is useful for navigating between pages. However, when performing filter-related functions on the current page, it's often necessary to set the state within the page itself. In such cases, a combined setter for search parameters and state would be more beneficial.

https://github.com/TanStack/router/assets/41789633/52751bd9-4d30-4a43-b9d5-62b095f1d433

image

Simple Usage

const countRoute = new Route({
  getParentRoute: () => rootRoute,

  validateSearch: (search) =>
    search as {
      count: number;
      id: string;
    },
  path: "count",
  component: PostComponent,
});

export function PostComponent() {
  const { count } = countRoute.useSearch();
  const setSearch = countRoute.useSetSearch();
  // replace false
  // const setSearch = countRoute.useSetSearch({ replace: false }});

  return (
    <div>
      Count {count}
      <button
        onClick={() => {
          setSearch({
            count: count + 1,
          });
        }}
      >
        setSearch
      </button>{" "}
    </div>
  );
}

gronxb avatar Jan 11 '24 15:01 gronxb

why wouldn't you use useNavigate to update the search params without navigating away?

schiller-manuel avatar Jan 11 '24 18:01 schiller-manuel

@schiller-manuel

I think useNavigate does more than just replace search.

It's possible with useNavigate, but useNavigate has a good scenario between screen moves, and I think what I've done is separation of concerns.

A scenario where you only want to control the search state on the current page, without page navigation.

For a more detailed scenario, the list is rendered on the current page and you can select a sort by filter. In this case, you'll only want to change and integrate the search state rather than navigate.

gronxb avatar Jan 12 '24 01:01 gronxb

I use useNavigate to update the state of a filtered, paginated list like this:

const navigate = useNavigate({from: '/foo'});
navigate({search: (prev) => ({...prev, page: page + 1 });

schiller-manuel avatar Jan 12 '24 21:01 schiller-manuel