为什么 React Router v6 似乎无法从 URL 中删除查询字符串参数?

Why does React Router v6 seem unable to remove query string param from URL?

我有一个应用程序,有时会加载查询字符串参数 t

开始时,我希望应用程序读取此参数(如果可用)并将其从 URL 中删除。

在根组件上,我这样做:

    const [searchParams, setSearchParams] = useSearchParams();

    if (searchParams.has('t')) {
        const token = searchParams.get('t');
        if (token) {
            searchParams.delete('t');
            const newParams: {[key: string]: string} = {};
            searchParams.forEach((value: string, key: string) => {
                newParams[key] = value;
            });
            console.log('setting params: ');
            console.dir(newParams);
            setSearchParams(newParams);
            AuthController.setAccessToken(token);
        }
    }

我看到它正确读取参数 t 并且 newParams 对象为空或仅包含其他参数,但由于某种原因 setSearchParams(newParams) 似乎没有做任何事情。参数 t 仍在 URL.

如何让它从 URL 中删除这个参数?

成功了!

这就是诀窍:

    const [searchParams, setSearchParams] = useSearchParams();
    const navigate = useNavigate();

    useEffect(() => {
        // remove the t parameter if it is present in the URL. This happens when we are redirected back from an OAuth
        // flow.
        if (searchParams.has('t')) {
            const token = searchParams.get('t');
            if (token) {
                searchParams.delete('t');
                const newParams: {[key: string]: string} = {};
                searchParams.forEach((value: string, key: string) => {
                    newParams[key] = value;
                });

                setSearchParams(newParams);
                navigate({
                    search: createSearchParams(newParams).toString(),
                }, {replace: true});

                AuthController.setAccessToken(token);
            }
        }

    }, [navigate, searchParams, setSearchParams]);

代码必须在useEffect并且navigate必须使用replace选项。现在参数已删除。

setSearchParams 更新程序功能实际上是“导航”,但对于 [=33= 的 queryString 部分].

useSearchParams

Note:

The setSearchParams function works like navigate, but only for the search portion of the URL. Also note that the second arg to setSearchParams is the same type as the second arg to navigate.

您不需要调用 navigate 来更新 queryString。问题是将此逻辑作为无意的副作用进行处理。将所有逻辑移至 useEffect 钩子中,您会发现它如您所料地工作。

const [searchParams, setSearchParams] = useSearchParams();

useEffect(() => {
  if (searchParams.has("t")) {
    const token = searchParams.get("t");
    if (token) {
      searchParams.delete("t");
      console.log("setting params:", { searchParams: searchParams.toString() });
      console.dir(searchParams.toString());
      setSearchParams(searchParams);
    }
  }
}, []);