繁体   English   中英

react-router v6 扩展搜索参数而不是替换它

[英]react-router v6 extending search params instead of replacing it

目前,执行setSearchParams(/* an object */)将替换现有的搜索参数。 如果我想扩展搜索参数而不是替换它们,例如添加一个新参数。 实现这一目标的最优雅方式是什么?

我知道我可以直接修改searchParams ,然后执行类似setSearchParams(newSearchParamsToObject)的操作。 然而,由于searchParams不是 object 而是URLSearchParams 代码会又长又丑。

编辑:因为有人似乎不明白我发布的内容

目前如果我们这样做:

const [searchParams, setSearchParams] = useSearchParams({ a: 1 });
setSearchParams({ b: 2 });

它会将searchParams替换为?b=2

我想要实现的是将b=2添加到现有搜索参数中,即最终搜索参数应该是?a=1&b=2

我想设置您要添加的搜索参数值会/应该是微不足道的。

const [searchParams, setSearchParams] = useSearchParams();

...

searchParams.set(newParamKey, newParamValue);
setSearchParams(searchParams);

编辑 react-router-v6-extending-search-params-instead-of-replacing-it

const [searchParams, setSearchParams] = useSearchParams();

const clickHandler = () => {
  searchParams.set("b", 2);
  setSearchParams(searchParams);
};

...

<button type="button" onClick={clickHandler}>
  Add "b=2" param
</button>

似乎也有效:

  • setSearchParams([...searchParams.entries(), ['b', 2]]);

您还可以使用URLSearchParams.append(name, value)方法,以防您需要多个“b”。

setSearchParams(searchParams.append('b', 2));

这不像你在这里修改 state。 您只是在操纵一个 URLSearchParams object。您不必担心它会发生变异。

路由器 v6 解决方案在这里(不知道是否也适用于以前的版本): setSearchParams接受一个 function 应该返回新的搜索参数,实际上给你以前的值

例如:

setSearchParams(prev => ([...prev.entries(), ['foo', 'bar']]);

这基本上就像@Drew Reese 的回答,但是使用之前的“状态”,就像您对 React 中的useState所做的那样。

这个版本 ->

setSearchParams(prev => ([...prev.entries(), ['foo', 'bar']]);

将添加相同的参数而不替换,就像这样->

?s=5&p=0&p=1

参数p是第二次添加的,而不是?s=5&p=1

React Router v6 有useSearchParams()方法返回一个数组,作为第一个值,一个获取实际搜索参数的方法,作为第二个,一个设置新值的方法,返回值类型定义是这样的: [URLSearchParams, SetURLSearchParams]你可以在官方文档中找到更多。

您可以在这个 codesandbox上看到一个完整的工作示例来解决您的问题。

这是一个总结:

import React, { useCallback, useMemo } from "react";
import { useSearchParams } from "react-router-dom";

function getRandomNumber() {
  return Math.floor(Math.random() * 1000) + 1;
}

function getAllParamsFromEntries(searchParamsEntity) {
  const finalValues = {};
  const entries = searchParamsEntity.entries();
  let isDone = false;

  while (!isDone) {
    const iteratorElement = entries.next();
    if (iteratorElement.value) {
      finalValues[iteratorElement.value[0]] = iteratorElement.value[1];
    }
    isDone = iteratorElement.done;
  }

  return finalValues;
}

const MainScreen = () => {
  const [searchParamsEntity, setSearchParams] = useSearchParams();

  const allSearchParams = useMemo(() => {
    return getAllParamsFromEntries(searchParamsEntity);
  }, [searchParamsEntity]);

  console.log(allSearchParams);

  const appendRandomSearchParam = useCallback(() => {
    setSearchParams((previousParams) => {
      const searchParams = getAllParamsFromEntries(previousParams);
      return {
        ...searchParams,
        [`randomParam${getRandomNumber()}`]: getRandomNumber()
      };
    });
  }, [setSearchParams]);

  return (
    <div>
      <p>Search params now: {JSON.stringify(allSearchParams, undefined, 2)}</p>
      <button onClick={appendRandomSearchParam}>Append</button>
    </div>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM