Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: setSearchParams is breaking Navigate behavior #11563

Closed
Wail-Sr opened this issue May 17, 2024 · 3 comments
Closed

[Bug]: setSearchParams is breaking Navigate behavior #11563

Wail-Sr opened this issue May 17, 2024 · 3 comments

Comments

@Wail-Sr
Copy link

Wail-Sr commented May 17, 2024

What version of React Router are you using?

6.20.1

Steps to Reproduce

I'm using the useRoutes hook from 'react-router-dom' for the creation of my Router

export default function Router() {
  return useRoutes([
    {
      element: (
        <Suspense fallback={<SplashScreen />}>
          <Outlet />
        </Suspense>
      ),
      children: [
        {
          path: '/',
          element: (
            <RequireAuth allowedRoles={['Pharmacy', 'Operator']}>
              <MainLayout>
                <Outlet />
              </MainLayout>
            </RequireAuth>
          ),
          children: [
            {
              index: true,
              element: <Navigate to="/feed" replace />,
            },
            {
              path: 'feed',
              element: <FeedPage />,
            },
            {
              path: 'favorite',
              element: <FavoritePage />,
            },
          ],
        },

        { path: '*', element: <Navigate to="/404" replace /> },
      ],
    },
  ]);
}

The main.jsx file

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <HelmetProvider>
    <BrowserRouter>
        <App />
    </BrowserRouter>
  </HelmetProvider>
);

And the App.js

<ThemeProvider>
  <Router />
</ThemeProvider>

In my <MainLayout />, I have the header and footer of the pages. The header has a search bar. When the app starts, I use useEffect to check if there are any search parameters in the query, and if there are, I fill in the search bar with them.

  const [searchParams, setSearchParams] = useSearchParams();
  const location = useLocation();
  const queryParams = {};

  useEffect(() => {
    setSearchKeyword(searchParams.get('q') || '');
  }, [location.search]);

  const handleFetchData = useCallback(() => {
    const queryParams = new URLSearchParams(searchParams);
    if (searchKeyword) {
      queryParams.set('q', searchKeyword);
    } else {
      queryParams.delete('q');
    }
    setSearchParams(queryParams.toString());              /////// here is the issue
  }, [searchKeyword]);

  const debouncedFetch = useCallback(debounce(handleFetchData, 500), [handleFetchData]);
  useEffect(() => {
      debouncedFetch();
      return () => {
        debouncedFetch.cancel();
      };
  }, [debouncedFetch]);

When you open the application at '/', it should automatically redirect to the feed page. However, it doesn't do that because of how setSearchParams is used in the handleFetchData function to retrieve the search query if it exists. Here's what's happening: it goes to '/', redirects to '/feed', then immediately returns to '/', resulting in a blank page (except for the header and the footer).

My theory is that when you first visit '/', setSearchParams captures the URL and attempts to extract the search parameters from it. But because JavaScript works asynchronously, it doesn't wait for this process to finish before moving on, so it quickly redirects to the '/feed' page. Since setSearchParams doesn't find any search terms, it just goes back to the original page ('/')

Expected Behavior

Automatically redirect to the feed page.

Actual Behavior

Redirect to the feed page, and instantly return to the '/' page. And stucks there.

@Wail-Sr Wail-Sr added the bug label May 17, 2024
@Stryzhevskyi
Copy link

Stryzhevskyi commented May 17, 2024

I'm observing a similar issue. Redirect with index route + <Navigate/> works as before on the version 6.11.0 and breaks on 6.11.1. Looks like this might caused the change in behaviour.

Update:
I've implemented custom "Navigate" component with navigate() inside useEffect and condition for data router dataRouterState.navigation.state !== "idle" and it fixed my case.

Update 2: only redirect is fixed but not the setSearchParams.

Update 3: according to this comment redirect should be performed with loader if data router is used.

@brophdawg11
Copy link
Contributor

Would you mind creating a working reproduction in codesandbox or stackblitz we can use to triage?

Copy link
Contributor

github-actions bot commented Jun 1, 2024

This issue has been automatically closed because we haven't received a response from the original author 🙈. This automation helps keep the issue tracker clean from issues that aren't actionable. Please reach out if you have more information for us! 🙂

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants