react-router 中的 useSearchParams 默认值

问题描述 投票:0回答:1

useSearchParams
钩子允许我们传入
defaultInit
参数:

declare function useSearchParams(
  defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];

type URLSearchParamsInit =
  | string
  | ParamKeyValuePair[]
  | Record<string, string | string[]>
  | URLSearchParams;

谁能帮我理解这个参数应该如何使用?当我使用此参数时,我的值不会添加到浏览器中的 URL 中。调用 hook 后我仍然需要调用 setter 来更新搜索参数。

例如:

const myDefaults = {
    one: 'A', 
    two: 'B'
};

// Passing in myDefaults here does not affect the URL in the browser
const [searchParams, setSearchParams] = useSearchParams(myDefaults);

// I have to additionally call useSearchParams to update the URL in the browser
useEffect(() => {
    setSearchParams(myDefaults);
}, []);

这是预期的吗?如果是这样,

defaultInit
参数的用途是什么?

reactjs react-router
1个回答
0
投票
使用

defaultInit
,当 URL 中不存在时,您可以从定义的默认搜索参数中读取,如果不存在,则不会更新 URL。

例如,如果

category
的默认值为
1
但用户打开的页面没有此查询参数:
https://example.com

在这种情况下,您可以为这些查询参数设置默认值,以便可以读取值:

const [searchParams] = useSearchParams({ category: '1' });
const { category } = searchParams;

这或多或少类似于以下内容:

const [searchParams] = useSearchParams();
const { category = '1' } = searchParams;

但是请注意,一旦您拨打了

setSearchParams
defaultInit
将不再生效。

参考:https://github.com/remix-run/react-router/blob/89049ce4ee1b265b78468f25eb494eef240a7e40/packages/react-router-dom/index.tsx#L1453-L1455


编辑:如果你想自动更新搜索参数(如果它不存在),你可以编写一个像这样的实用函数(未测试):

import { useRef } from 'react';
import { createSearchParams, useSearchParams } from 'react-router-dom';

function useSearchParamsWithUpdate(defaultInit) {
  const [searchParams, setSearchParams] = useSearchParams(defaultInit);
  const defaultSearchParams = useRef(createSearchParams(defaultInit));

  useEffect(() => {
    const def = defaultSearchParams.current;

    const update = {};
    let needUpdate = false;

    def.forEach((v, k) => {
      if (!searchParams.has(k)) {
        update[k] = v;
        needUpdate = true;
      }
    });

    if (needUpdate) setSearchParams(update, { replace: true });
  }, [searchParams]);

  return [searchParams, setSearchParams];
}
© www.soinside.com 2019 - 2024. All rights reserved.