在具有在背景中渲染的父路由的路由上渲染模态



我正在使用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组件放在一起,并移除父Routeexact属性。通过这种方式,两个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

只有当您从父级导航到它时,它们才会有条件地将其渲染为模态。您可以对其进行修改,使其始终呈现为模态。

最新更新