我正在使用ReachUIDialog
来呈现对话框(模态(。Dialog
可在路由products/create/
上路由,如您在下面的代码中所见。
当我路由到products/create
时,是否可以同时渲染ProductsTable
(位于父路由products/
(和Dialog
,以便在模态的背景中看到ProductsTable
组件?我希望通过react-router
实现这一点。
这就是代码现在的样子:
...
import { Switch, Route, useRouteMatch, match, useHistory, } from "react-router-dom";
import { Dialog } from "@reach/dialog";
export function ProductsPage() {
const { url }: match = useRouteMatch();
const { push } = useHistory();
const gotToCreateProduct = () => push(`${url}/create`);
return (
<Switch>
<Route exact path={url}>
<Page title="Products" onCreateButtonClick={gotToCreateProduct}>
<ProductsTable></ProductsTable>
</Page>
</Route>
<Route path={`${url}/create`}>
<Dialog isOpen={true} onDismiss={() => push(url)}>
<ProductForm></ProductForm>
</Dialog>
</Route>
</Switch>
);
}
我自己想好了,基本上,您只需要将两个Switch
组件放在一起,并移除父Route
的exact
属性。通过这种方式,两个Switch
都将具有匹配并呈现它们的路由。有道理&它是有效的。
return (
<>
<Switch>
<Route path={url}>
<Page title="Products" onCreateButtonClick={gotToCreateProduct}>
<ProductsTable></ProductsTable>
</Page>
</Route>
</Switch>
<Switch>
<Route path={`${url}/create`}>
<Dialog show={true} title={'Create product'}
onClose={() => push(url)}><CreateProduct></CreateProduct></Dialog>
</Route>
<Route path={`${url}/:productId/edit`}>
<Dialog show={true} title={'Edit product'} onClose={() => push(url)}><EditProduct></EditProduct></Dialog>
</Route>
</Switch>
</>
);
React路由器v6
您必须在嵌套组件中使用Outlet;<BrowserRouter>
<Routes>
<Route path="/home" element={<Home />}>
<Route path="modal" element={<Modal />} />
</Route>
</Routes>
</BrowserRouter>
在Home组件中添加一个Outlet;
import { Outlet } from "react-router-dom";
export default function Home(){
return(
<>
Home Code is here
<Outlet />
</>
)
}
所以现在,无论何时打开路由/home/modal
,默认情况下都会打开模态。确保默认情况下保持道具isOpen
为true,因为渲染现在将由react路由器控制。
@Akshay K Nair的答案几乎是完美的,只是<Outlet />
的位置不对。<Outlet />
的正确用法是让父路由器组件对其进行渲染(请在此处阅读更多信息(。看看这个React Router Dom v6示例:
路由器
export const router = createBrowserRouter([
{
path: "/",
element: <Home />,
children: [
{
path: "/:id",
element: (
<ModalRoute>
<Detail />
</ModalRoute>
),
},
],
},
])
父组件
const Home = () => {
return (
<>
Insert parent code
<Outlet />
</>
)
}
莫代尔路线
const ModalRoute = ({ children }) => {
const [opened, setOpened] = useState(false)
const location = useLocation()
const navigate = useNavigate()
useEffect(() => {
const id = location.pathname.split("/")[1]
if (id) {
setOpened(true)
}
}, [location.pathname])
const handleClose = () => {
navigate("/")
setOpened(false)
}
return (
<Modal opened={opened} onClose={handleClose}>
{children}
</Modal>
)
}
通过将您的第一条路线更改为
<Route path={`${url}*`}>
<Page title="Products" onCreateButtonClick={gotToCreateProduct}>
<ProductsTable></ProductsTable>
</Page>
</Route>
每个以url开头的路由都会显示您的组件通过删除交换机组件,您将能够匹配多个路由
这应该是一个开始:https://reactrouter.com/web/example/modal-gallery
只有当您从父级导航到它时,它们才会有条件地将其渲染为模态。您可以对其进行修改,使其始终呈现为模态。