我正在尝试构建一个带有选项卡的页面。我希望每个选项卡都有自己的路线。
/project/:id/a
/project/:id/b
/project/:id/c
我在我的
<App />
组件中创建路由器。
App.tsx
import { createBrowserRouter } from 'react-router-dom';
import { PageProject } from './pages/PageProject';
const router = createBrowserRouter([
{
path: '/project/:id?/:tab?',
element: <PageProject />,
},
]);
这可行,但我在
组件中有一些状态,我想将其传递给每个选项卡组件,因此我不是在 App.tsx 中定义
<PageProject />
路由,而是尝试在within 中定义它们
children
。
PageProject.tsx
<PageProject>
这似乎不起作用。有没有办法可以将状态从父组件传递到子组件?
import { Link, Route, Routes, useParams } from 'react-router-dom';
import { PanelA } from './PanelA';
import { PanelB } from './PanelB';
import { PanelC } from './PanelC';
export const PageProject = () => {
const { id } = useParams();
const [project, setProject] = useState(null);
// project is fetched from an API using the "id" param and set in state
return (
<section>
<div className="tabs">
<Link to={`/project/${id}/a">A</Link>
<Link to={`/project/${id}/b">B</Link>
<Link to={`/project/${id}/c">C</Link>
</div>
<div className="panels">
<Routes>
<Route element={<PanelA project={project} />} path={`/project/${id}/a`} />
<Route element={<PanelB project={project} />} path={`/project/${id}/b`} />
<Route element={<PanelC project={project} />} path={`/project/${id}/c`} />
</Routes>
</div>
</section>
);
}
提供的
<Outlet>
组件,它将
react-router-dom
传递给所有子路由。
https://reactrouter.com/en/main/hooks/use-outlet-context
子路由是与所有其他路由一起定义的。
App.tsx
context
请注意,我删除了 import { PanelA } from './PanelA';
const App = () => {
const router = createBrowserRouter([
{
path: '/project/:id?',
element: <PageProject />,
children: [
{
element: <PanelA />
index: true
},
{
element: <PanelA />
path: 'a'
}
]
},
]);
}
参数,因为该段现在被定义为路径。我还添加了
:tab?
两次 - 一次作为
<PanelA>
组件 - 在父级上渲染的默认组件 - 然后再次在明确定义
index
的地方添加。
PageProject.tsx
path
然后子路由可以使用 import { Project } from '@types';
import { Link, Outlet, useParams } from 'react-router-dom';
export const PageProject = () => {
const { id } = useParams();
const [project, setProject] = useState<Project | null>(null);
// project is fetched from an API using the "id" param and set in state
return (
<section>
<div className="tabs">
<Link to={`/project/${id}/a`}>A</Link>
<Link to={`/project/${id}/b`}>B</Link>
<Link to={`/project/${id}/c`}>C</Link>
</div>
<div className="panels">
<Outlet context={{ project }} />
</div>
</section>
);
}
访问
context
。
面板A.tsx
useOutletContext()