[英]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);
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.