是的,完全可以在保持DOM渲染但隐藏的情况下切换路由!如果您正在构建SPA,则最好使用客户端路由。这使得您的任务变得容易:
为了隐藏组件,同时保持其在DOM中,可以使用以下任一CSS:
1. `.hidden { visibility: hidden }` 仅隐藏未使用的组件/路由,但仍保留其布局。
2. `.no-display { display: none }` 隐藏未使用的组件/路由,包括其布局。
对于路由,使用 `react-router-dom`,您可以在 `Route` 组件上使用
function children prop:
children: func
有时候你需要渲染路径是否与位置匹配。在这种情况下,你可以使用函数 children prop。它的工作方式与render完全相同,只是无论是否匹配都会被调用。当路由未能匹配URL时,children render prop接收所有相同的路由props作为组件和渲染方法,除非match为空。这使您能够根据路由是否匹配动态调整UI。
在我们的案例中,如果路由不匹配,我将添加隐藏的CSS类:
App.tsx:
export default function App() {
return (
<div className="App">
<Router>
<HiddenRoutes hiddenClass="hidden" />
<HiddenRoutes hiddenClass="no-display" />
</Router>
</div>
);
}
const HiddenRoutes: FC<{ hiddenClass: string }> = ({ hiddenClass }) => {
return (
<div>
<nav>
<NavLink to="/1">to 1</NavLink>
<NavLink to="/2">to 2</NavLink>
<NavLink to="/3">to 3</NavLink>
</nav>
<ol>
<Route
path="/1"
children={({ match }) => (
<li className={!!match ? "" : hiddenClass}>item 1</li>
)}
/>
<Route
path="/2"
children={({ match }) => (
<li className={!!match ? "" : hiddenClass}>item 2</li>
)}
/>
<Route
path="/3"
children={({ match }) => (
<li className={!!match ? "" : hiddenClass}>item 3</li>
)}
/>
</ol>
</div>
);
};
styles.css:
.hidden {
visibility: hidden;
}
.no-display {
display: none;
}
使用CodeSandbox: https://codesandbox.io/s/hidden-routes-4mp6c?file=/src/App.tsx进行工作。
比较visibility: hidden
和display: none
的不同行为。
请注意,在两种情况下,所有组件仍然挂载到DOM中!您可以使用浏览器开发工具中的检查工具进行验证。
可重用解决方案
对于可重用的解决方案,您可以创建一个可重用的HiddenRoute组件。
在以下示例中,我使用了钩子useRouteMatch
,类似于children
Route属性的工作方式。根据匹配结果,我向新组件的子级提供了隐藏类:
import "./styles.css";
import {
BrowserRouter as Router,
NavLink,
useRouteMatch,
RouteProps
} from "react-router-dom";
const HiddenRoute = (props: RouteProps) => {
const match = useRouteMatch(props);
return <span className={match ? "" : "no-display"}>{props.children}</span>;
};
export default function App() {
return (
<div className="App">
<Router>
<nav>
<NavLink to="/1">to 1</NavLink>
<NavLink to="/2">to 2</NavLink>
<NavLink to="/3">to 3</NavLink>
</nav>
<ol>
<HiddenRoute path="/1">
<li>item 1</li>
</HiddenRoute>
<HiddenRoute path="/2">
<li>item 2</li>
</HiddenRoute>
<HiddenRoute path="/3">
<li>item 3</li>
</HiddenRoute>
</ol>
</Router>
</div>
);
}
可复用解决方案的CodeSandbox工作示例:https://codesandbox.io/s/hidden-routes-2-3v22n?file=/src/App.tsx
HashRouter
或MemoryRouter
? - Slbox