[英]Is it possible to use multiple outlets in a component in React-Router V6
I am using React Router v6 in an application.我在应用程序中使用 React Router v6。 I have a layout page, which uses an outlet to then show the main content.
我有一个布局页面,它使用一个插座来显示主要内容。 I would also like to include a title section that changes based on which path has been matched, but I am unsure how to do this.
我还想包括一个标题部分,该部分根据匹配的路径而变化,但我不确定如何执行此操作。
function MainContent() {
return (
<div>
<div>{TITLE SHOULD GO HERE}</div>
<div><Outlet /></div>
</div>
);
}
function MainApp() {
return (
<Router>
<Routes>
<Route path="/projects" element={<MainContent />} >
<Route index element={<ProjectList />} title="Projects" />
<Route path="create" element={<CreateProject />} title="Create Project" />
</Route>
<Routes/>
</Router>
);
}
Is something like this possible?这样的事情可能吗? Ideally, I would like to have a few other props besides title that I can control in this way, so a good organization system for changes like this would be great.
理想情况下,除了标题之外,我还希望有一些我可以通过这种方式控制的其他道具,所以一个好的组织系统来进行这样的更改会很棒。
The most straightforward way would be to move the title
prop to the MainContent
layout wrapper and wrap each route individually, but you'll lose the nested routing.最直接的方法是将
title
属性移动到MainContent
布局包装器并单独包装每个路由,但是您将丢失嵌套路由。
An alternative could be to create a React context to hold a title
state and use a wrapper component to set the title.另一种方法是创建一个 React 上下文来保存
title
state 并使用包装器组件来设置标题。
const TitleContext = createContext({
title: "",
setTitle: () => {}
});
const useTitle = () => useContext(TitleContext);
const TitleProvider = ({ children }) => {
const [title, setTitle] = useState("");
return (
<TitleContext.Provider value={{ title, setTitle }}>
{children}
</TitleContext.Provider>
);
};
Update MainContent
to access the useTitle
hook to get the current title
value and render it.更新
MainContent
以访问useTitle
挂钩以获取当前title
值并呈现它。
function MainContent() {
const { title } = useTitle();
return (
<div>
<h1>{title}</h1>
<div>
<Outlet />
</div>
</div>
);
}
The TitleWrapper
component. TitleWrapper
组件。
const TitleWrapper = ({ children, title }) => {
const { setTitle } = useTitle();
useEffect(() => {
setTitle(title);
}, [setTitle, title]);
return children;
};
And update the routed components to be wrapped in a TitleWrapper
component, passing the title
prop here.并更新路由组件以包装在
TitleWrapper
组件中,在此处传递title
属性。
<Route path="/projects" element={<MainContent />}>
<Route
index
element={
<TitleWrapper title="Projects">
<ProjectList />
</TitleWrapper>
}
/>
<Route
path="create"
element={
<TitleWrapper title="Create Project">
<CreateProject />
</TitleWrapper>
}
/>
</Route>
In this way, MainContent
can be thought of as UI common to a set of routes whereas TitleWrapper
( you can choose a more fitting name ) can be thought of as UI specific to a route.这样,
MainContent
可以被认为是一组路由的通用 UI,而TitleWrapper
(您可以选择更合适的名称)可以被认为是特定于路由的 UI。
I was facing the same issue for a left-right layout: changing sidebar content and main content, without repeating styling, banner, etc.对于左右布局,我遇到了同样的问题:更改侧边栏内容和主要内容,而不重复样式、横幅等。
The simplest approach I found was to remove nested routing, and create a layout component in which I feed the changing content through properties.我发现的最简单的方法是删除嵌套路由,并创建一个布局组件,我在其中通过属性提供不断变化的内容。
Layout component (stripped for this post):布局组件(为这篇文章删除):
export function Layout(props) {
return (
<>
<div class="left-sidebar">
<img id="logo" src={Logo} alt="My logo" />
{props.left}
</div>
<div className='right'>
<header className="App-header">
<h1>This is big text!</h1>
</header>
<nav>
<NavLink to="/a">A</NavLink>
|
<NavLink to="/b">B</NavLink>
</nav>
<main>
{props.right}
</main>
</div>
</>
);
}
Usage in react router:在反应路由器中的用法:
<Route path="myPath" element={
<Layout left={<p>I'm left</p>}
right={<p>I'm right</p>} />
} />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.