英文:
Using <Navigate> with `react-router-dom` and `next.js`
问题
我有一个稍微奇怪的设置,我将所有需要动态路由的路由重定向到 index.tsx
,并使用 react-router-dom
处理这些客户端路由。我主要不得不这样做,因为似乎在将 Next.js 站点导出为静态站点时,Next.js 会为每个路由生成页面,所以我无法在 JavaScript 中生成新路由。
然而,当使用 react-router-dom
的 <Navigate />
组件时,这个设置似乎无法正常工作。例如,
// index.tsx
const Home: FC = () => {
// 目前会在本地生成房间 id,但我们应该在服务器端执行此操作,以确保唯一性。
return (
<Router>
<Routes>
<Route path="/" element={<RedirectToMain />} />
<Route path="/:roomId" element={<Main />} />
</Routes>
</Router>
);
}
const RedirectToMain: FC = () => {
const generatedRoomId = Array(5)
.fill(null)
.map(x => alphabet[Math.floor(26 * Math.random())])
.join('');
console.log('navigating');
return <Navigate to={generatedRoomId} />;
}
const Main: FC = () => {
const { roomId } = useParams();
console.log(roomId);
// 我们必须等待 roomId 加载后才能运行。
if (!roomId || roomId.length === 0) {
return <></>;
}
return (
<WebSocketProvider roomId={roomId}>
<MinesAppBar url={`http://mineswpr.io/${roomId}`} />
<Board />
</WebSocketProvider>
);
};
在本地运行 yarn next dev
时,它会重定向到 localhost:3000/ABCDE
,然后 URL 又会变回 localhost:3000/
。将其设置为将所有流量重定向到 /index.html
的静态站点时,似乎会不断调用 <Navigate />
。
如何解决这个问题?
英文:
So I have a slightly weird setup where I redirect all routes where I need dynamic routing to index.tsx
and use react-router-dom
to handle those routes Client-side. I mainly had to do this because it seems that when exporting Next.js sites to a static site, Next.js generates pages for each route, so I can't generate new routes in Javascript.
However, this setup doesn't seem work properly when using react-router-dom
's <Navigate />
component. For example,
// index.tsx
const Home: FC = () => {
// Currently going to generate the room id locally, but we
// should do this server side so that we can guarantee uniqueness.
return (
<Router>
<Routes>
<Route path="/" element={<RedirectToMain />} />
<Route path="/:roomId" element={<Main />} />
</Routes>
</Router>
);
}
const RedirectToMain: FC = () => {
const generatedRoomId = Array(5)
.fill(null)
.map(x => alphabet[Math.floor(26 * Math.random())])
.join('');
console.log('navigating');
return <Navigate to={generatedRoomId} />;
}
const Main: FC = () => {
const { roomId } = useParams();
console.log(roomId);
// We must wait for roomId to load before running.
if (!roomId || roomId.length === 0) {
return <></>;
}
return (
<WebSocketProvider roomId={roomId}>
<MinesAppBar url={`http://mineswpr.io/${roomId}`} />
<Board />
</WebSocketProvider>
);
};
When running this locally with yarn next dev
, it redirects to localhost:3000/ABCDE
and then the url changes back to localhost:3000/
. When running this as a static site which is setup to redirect all traffic to /index.html
, it seems to constantly call <Navigate />
.
How can I fix this issue?
答案1
得分: 1
你需要使用 useNavigate
钩子代替 Navigate
。
Navigate
组件适用于 React 组件类,引用自 react-router-dom 文档,> 在 React.Component 子类中使用此功能,无法使用钩子,所以由于你正在使用函数组件,应该改为使用钩子,因此你的代码应该像这样:
const navigate = useNavigate()
const testFn = () => { return navigate('/') }
英文:
You need to use useNavigate hook instead of Navigate
the Navigate component works in React component classes,
quoting the react-router-dom docs
> use this feature in a React.Component subclass where hooks are not able to be used
and since you're using functional components you should instead be using hooks therefore your code should look something like this
const navigate = useNavigate()
const testFn = () => { return navigate('/') }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论