【发布时间】:2021-10-23 00:02:59
【问题描述】:
我在 react 中工作,我有一个带有一些过滤器的商店页面。当我应用过滤器时,我还想将此过滤器添加到 url 但不重新加载页面。
我的意思是这样的:
currentUrl : something.com
newUrl : something.com/brand-nike
我想更改网址而不刷新。
我已经尝试过这些代码,但都重新加载了页面:
window.history.pushState({ path: url }, "", url);
window.history.replaceState(null, "", url);
我也在使用react-router-dom 进行路由。
这是我的App.js:
return (
<ToastProvider>
<ShopFilterContext.Provider value={shopFilterHook}>
<CartContext.Provider value={cartHook}>
<React.Fragment>
<Router basename={BASENAME}>{renderRoutes(routes)}</Router>
</React.Fragment>
</CartContext.Provider>
</ShopFilterContext.Provider>
</ToastProvider>
);
这是renderRoutes函数:
export const renderRoutes = (routes = []) => {
return (
<Suspense fallback={<Loader />}>
<Switch>
{routes.map((route, i) => {
const Guard = route.guard || Fragment;
const Layout = route.layout || Fragment;
const Component = route.component;
return (
<Route
key={i}
path={route.path}
exact={route.exact}
render={(props) => {
props["layoutObj"] = route.layoutObj;
return (
<Guard>
<Layout>{route.routes ? renderRoutes(route.routes) : <Component {...props} />}</Layout>
</Guard>
);
}}
/>
);
})}
</Switch>
</Suspense>
);
};
这是routes变量
const routes = [
{
path: "/account/*",
layout: NifsyLayout,
routes: [
{
exact: true,
path: "/account/*",
component: lazy(() => import("./pages/MyAccount")),
},
{
path: "/account/*",
exact: true,
component: () => <Redirect to={ACCOUNT_URL} />,
},
],
},
{
path: "/search/*",
layout: NifsyLayout,
routes: [
{
exact: true,
path: "/search/*",
component: lazy(() => import("./pages/Shop")),
},
{
path: "/search/*",
exact: true,
component: () => <Redirect to={ACCOUNT_URL} />,
},
],
},
{
path: "*",
layout: NifsyLayout,
routes: [
{
exact: true,
path: "/not-found",
component: lazy(() => import("./pages/NotFound")),
},
{
path: "*",
exact: true,
component: () => <Redirect to={BASE_URL} />,
},
],
},
];
这是用于导航的:(历史是来自useHistory的钩子)
let url = "/search";
if (filter.category) url = url + "/" + filter.category;
if (filter.brands) {
for (let i = 0; i < filter.brands.length; i++) {
url = url + filter.brands[i];
}
}
if (filter.collections) {
for (let i = 0; i < filter.collections.length; i++) {
url = url + filter.collections[i];
}
}
url = url + "?q=" + filter.keyword;
url = url + "&start=" + filter.start;
url = url + "&size=" + filter.size;
url = url + "&sortby=" + filter.sort;
url = url + "&filter=" + (typeof filter.filters == "string" ? filter.filters : JSON.stringify(filter.filters));
// multi refresh
//window.history.pushState({ path: url }, "", url);
//window.history.replaceState(null, "Nifsy", url);
history.push(url);
【问题讨论】:
-
你能澄清一下用例吗? “在不刷新页面的情况下向url添加新参数”是什么意思?
-
您只是想从“/”导航到“/brand-nike”吗?请分享您的路由代码和您尝试进行导航的代码。 stackoverflow.com/help/minimal-reproducible-example
-
为什么要在同一路径上渲染多个路由?如果您的搜索路径恰好是带有斜杠的
"/search/*",那么您永远无法将"/search"与查询参数匹配。我看不出您如何计算url有任何问题,所以我怀疑您的组件在安装后不会寻找路线更改。你从哪里做导航?我们仍然需要一个更全面的代码示例。 -
其实我的搜索路径可能会因过滤器的不同而不同,
/search/category-women/或/search/category-women/brand-nike/collection-winter/ -
在这种情况下,您可能需要一个更像
"/search/:category/:brand/:collection"的路径,以便您可以访问 URL 的各个路径段。您还应该注意react-router-dom路由匹配参数 不是 与 URL queryString 参数相同的东西。见handling query parameters。