如何在不刷新Next JS(React(中的页面的情况下删除或更新查询参数?
- 用户位于URL
/about?login=success&something=yes
上 - 单击按钮并从URL中删除
?login=success&something=yes
,而不刷新页面。单击按钮后的URL将为/about
如何实现?
正如本线程中提到的,我知道使用Router可以删除查询参数或查询字符串。但是,useLocation
和useHistory
在next/router
上不可用。
您可以使用next/router
删除URL中的查询参数。
const router = useRouter();
router.replace('/about', undefined, { shallow: true });
使用replace
可以防止在历史记录中添加新的URL条目(否则只使用push
(,使用shallow: true
可以在不运行数据获取方法的情况下更改URL。这将导致重新渲染,但不会刷新页面本身。
上述解决方案将从URL中删除所有查询参数。如果只想删除特定的参数,可以使用下面的代码。
const removeQueryParam = (param) => {
const { pathname, query } = router;
const params = new URLSearchParams(query);
params.delete(param);
router.replace(
{ pathname, query: params.toString() },
undefined,
{ shallow: true }
);
};
removeQueryParam('something');
根据历史记录,您可以使用history.replaceState
来实现这一点。
window.history.replaceState(null, '', '/about')
我对类似问题的解决方案是:
push(`${asPath.split('?')[0]}?comp=${id}`);
或者如果你想拥有可重复使用的功能:
function delQuery(asPath) {
return asPath.split('?')[0]
}
...
const {push, asPath} = useRouter()
push(`${delQuery(asPath)}?comp=${id}`);
在删除一个特定查询参数(例如shouldRefetchUser
(时,通常想要keep pathname and all other query params
,您可以这样做:
const router = useRouter()
const { pathname, query } = router
delete router.query.shouldRefetchUser
router.replace({ pathname, query }, undefined, { shallow: true })
(@julialves的升级答案(
如果您想从查询中删除单个或多个参数,
const router = useRouter();
/**
* If removeList is empty, the function removes all params from url.
* @param {*} router
* @param {*} removeList
*/
const removeQueryParamsFromRouter = (router, removeList = []) => {
if (removeList.length > 0) {
removeList.forEach((param) => delete router.query[param]);
} else {
// Remove all
Object.keys(router.query).forEach((param) => delete router.query[param]);
}
router.replace(
{
pathname: router.pathname,
query: router.query
},
undefined,
/**
* Do not refresh the page
*/
{ shallow: true }
);
};
const anyFunction = () => {
// "/about?firstParam=5&secondParam=10"
removeQueryParamsFromRouter(router, ['myParam']);
// "/about?secondParam=10"
};
您可以简单地使用">路由器.推送";或">路由器。替换";用">浅:真";,这将在不重新加载页面的情况下删除查询参数。
const router = useRouter();
router.replace('/about', undefined, { shallow: true });
或者,如果你想删除单个查询,那么这个快速简单的方法将帮助你
例如/关于login=成功&something=yes
const router = useRouter();
// perform this inside function call or button click etc
delete router.query.something;
router.push(router)
现在更新的路线将是
/about?login=成功
对于next/router和typescript,上面的答案似乎都不起作用了。
以下代码段获取所有查询参数,并按键删除其中一个,同时保持所有其他参数不变。
const { push, query } = useRouter();
const removeQueryParam = (param) => {
const updatedQuery = query;
delete updatedQuery[param];
push({ query: updatedQuery }, undefined, { shallow: true });
}
用法(在clickHandler或任何位置(:
removeQueryParam('queryParamName');
注意:如果您不想将新URL添加到浏览器历史记录后堆栈,请使用router.replace
而不是router.push
。
也许这个解决方案会更简洁一些:
const { query, replace } = useRouter();
const setActiveTab = useCallback((tabName: string) => {
const { group, ...paramsExceptGroup } = query || {};
replace(
{
query: tabName === defaultTabName ? paramsExceptGroup : { ...paramsExceptGroup, group: tabName },
},
undefined,
{ shallow: true },
).then();
}, [query, defaultTabName]);
因此,如果";选项卡";默认情况下,我使用排列运算符将其删除并从查询中删除。
我们可以使用next/router
中的useRouter
钩子来访问当前路由和查询参数要在不刷新页面的情况下删除或更新参数,我们可以使用路由器对象的push
方法。
以下是我们如何从URL中删除查询参数的示例:
const router = useRouter();
function removeQueryHandler() {
const { pathname } = router;
router.push({ pathname });
}
代码沙盒:链接
另一种方法:
我们也可以使用浅层路由来删除或更新查询参数,而无需在Next.js中触发整页刷新
function removeQueryHandler() {
const { pathname } = router;
router.push({ pathname }, undefined, { shallow: true });
}
您可以通过[]从路由器对象中删除查询参数:
const router = useRouter();
router.query.something = [];
import {NextRouter} from 'next/router'
export const removeQueryParams = (
router: NextRouter,
paramsToRemove: Array<string> = []
) => {
if (paramsToRemove.length > 0) {
paramsToRemove.forEach((param) => delete router.query[param])
} else {
// Remove all query parameters
Object.keys(router.query).forEach((param) => delete router.query[param])
}
router.replace(
{
pathname: router.pathname,
query: router.query,
},
undefined,
/**
* Do not refresh the page when the query params are removed
*/
{shallow: true}
)
}
const anyFunction = () => {
// "/about?firstParam=5&secondParam=10"
removeQueryParamsFromRouter(router, ['myParam']);
// "/about?secondParam=10"
};
原始答案
这里提到的原始答案抛出了一个错误,因为对象是未定义的,而且它是它的typescript版本
当您知道要删除的查询参数时,这是一个很好的方法https://github.com/jbranchaud/til/blob/master/nextjs/remove-a-query-param-from-the-url.md
const router = useRouter();
useEffect(() => {
// extract the value from the query params
const { someKey, ...updatedQuery } = router.query;
// create an updated router path object
const newPathObject = {
pathname: router.pathname,
query: updatedQuery,
};
// update the URL, without re-triggering data fetching
void router.push(newPathObject, undefined, { shallow: true });
}, [router]);
这对你来说应该很好:
router.replace('/about', undefined, { shallow: true });
浅路由不会导致页面刷新和数据重蚀刻。点击此处了解更多信息。
即使上述解决方案在不引起刷新的情况下删除了查询参数,它们也会导致重新渲染。
不幸的是,Nextjs没有内置的解决方案可以在不导致重新渲染的情况下删除查询参数。但是,有一个本地解决方案:
window.history.replaceState({ ...window.history.state, as: '/about', url: '/about' }, '', '/about');
Nextjs具有useRouter
钩子,可用于以编程方式更改url。链接到文档。