我正在尝试将
React-Admin
AdminDashboard
组件集成到使用 React-Router 进行导航的更大的 React 应用程序中。但是,我遇到了 AdminDashboard
无法按预期渲染或工作的问题。
当我最初直接在
AdminDashboard
中使用 App.js
时,一切正常,并且 URL 显示为 "http://localhost:3000/AdminDashboard/#/users"
。但是,将 AdminDashboard
重构为单独的组件后,页面无法加载,并且 URL 意外更改为 "http://localhost:3000/users"
或 "http://localhost:3000/posts"
,如资源中第一个。
此问题仅在将
AdminDashboard
代码移至其自己的组件中后才出现,这表明路由或组件集成的处理方式存在潜在问题。
我首先制作了像 Blog.logrocket
这样的应用程序重构之前
AdminDashboard.jsx
不是一个单独的组件,它位于app.js内部,如下代码所示:
//here all the imports
const app = () => {
return (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
<Resource name="users" list={UserList} />
</Admin>
);
};
// exporting the app, and all this was working fine
下面是我最新的代码设置,但它不起作用:
AdminDashboard.jsx:
import React from 'react';
import { Admin, Resource } from 'react-admin';
import UserList from './User';
import PostList from './Posts';
import restProvider from 'ra-data-simple-rest';
const dataProvider = restProvider('http://localhost:3000');
const AdminDashboard = () => {
return (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
<Resource name="users" list={UserList} />
</Admin>
);
};
export default AdminDashboard;
App.js:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Header from "./components/Layout/Header";
import Footer from "./components/Layout/Footer";
import Homepage from "./components/Homepage";
import NotFound from "./components/Layout/NotFound";
import PrivateRoute from "./components/Routing/PrivateRoute";
import Login from "./components/Admin/Login";
import AdminDashboard from "./components/Admin/AdminDashboard";
const App = () => {
return (
<Router>
<div className="App">
<Routes>
<Route path="/" element={<LayoutsWithHeader />}>
<Route path="*" element={<NotFound />} />
<Route exact path="/" element={<Homepage />} />
<Route path="/login" element={<Login />} />
<Route element={<PrivateRoute />}>
<Route path="/AdminDashboard/*" element={<AdminDashboard />} />
</Route>
</Route>
</Routes>
</div>
</Router>
);
};
const LayoutsWithHeader = () => {
return (
<>
<Header />
<Outlet />
<Footer />
</>
);
};
export default App;
range.js
module.exports = (req, res, next) => {
res.header("Content-Range", "users 0-20/20");
res.header("Content-Range", "Posts 0-20/20");
next();
};
我最新的代码结构:
appname/
├── client/ # Client-side React application
│ ├── public/ # Static files
│ ├── src/
│ │ ├── components/
│ │ │ ├── Admin/
│ │ │ │ ├── AdminDashboard.jsx # Admin dashboard component
│ │ │ │ ├── Login.jsx # Login component
│ │ │ │ ├── Posts.jsx # Posts component
│ │ │ │ └── Users.jsx # Users component
│ │ │ ├── Layout/
│ │ │ │ ├── Footer.jsx # Footer layout component
│ │ │ │ ├── Header.jsx # Header layout component
│ │ │ │ └── NotFound.jsx # Not found component
│ │ │ ├── Routing/
│ │ │ │ └── PrivateRoute.jsx # Private route component
│ │ │ └── Homepage.jsx # Homepage component
│ │ ├── App.css # Main CSS file for the app
│ │ ├── App.js # Main JavaScript file for React app
│ │ ├── App.test.js # Test file for the app
│ │ ├── index.css # CSS file for index component
│ │ ├── index.js # Entry point for React app
│ │ ├── logo.svg # Logo file
│ │ ├── reportWebVitals.js # Web vitals report utility
│ │ └── setupTests.js # Setup file for tests
│ ├── package.json # NPM package file for the client
│ └── node_modules/ # Node modules for the client
│
├── server/ # Server-side Node.js application
│ ├── Controllers/ # Controllers for server logic
│ ├── middlewares/ # Middlewares for the server
│ ├── Models/ # Data models for the server
│ ├── Routers/ # Route definitions for the server
│ ├── config/
│ │ └── config.env # Environment config file
│ ├── node_modules/ # Node modules for the server
│ ├── uploads/ # Uploaded files directory
│ ├── package-lock.json # NPM lock file for server
│ ├── package.json # NPM package file for the server
│ ├── range.js # Additional JavaScript file
│ ├── server.js # Entry point for Node.js server
│ └── db.json # Mock database JSON file
│
├── .gitignore # Git ignore file
├── links.json # Additional JSON file
├── package-lock.json # NPM lock file for root
├── package.json # NPM package file for root
├── README.md # Readme file for the project
└── request.log # Log file for server requests
我检查了路由设置,虽然我最初认为这不是问题,但根据我目前的理解,我开始怀疑它可能与问题有关。
额外代码和信息:
标题中的链接:
<Link to="/AdminDashboard">
AdminDashboard
</Link>
</>
部分客户端package.json:
"proxy": "http://localhost:5000",
"dependencies": {
"react": "^18.2.0",
"react-admin": "^4.16.4",
"react-dom": "^18.2.0",
部分服务端package.json:
"scripts": {
"server": "json-server --watch db.json --port 5000 --middlewares ./range.js",
"client": "npm start --prefix ./client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
使用像
"http://localhost:3000/AdminDashboard/#/users"
这样的 URL 意味着您之前使用过哈希路由。该应用程序由 "http://localhost:3000/AdminDashboard/#"
提供/托管,可访问的路线是:
"/"
根/主页"/users"
用户页面"/posts"
帖子页面然后您添加了客户端路由,例如
react-router-dom
并使用 BrowserRouter
。看起来 BrowserRouter
认为它是从 "http://localhost:3000"
运行的,因此上面的相同路线相对于 this 有效。我怀疑您可以只向路由器添加一个 basename
道具并编辑“管理仪表板”以省略路径前缀。这会将路由器配置为在 URL 中的特定基本名称下运行。
示例:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
...
const App = () => {
return (
<Router basename="/AdminDashboard">
<div className="App">
<Routes>
<Route element={<LayoutsWithHeader />}>
<Route path="/" element={<Homepage />} />
<Route path="/login" element={<Login />} />
<Route element={<PrivateRoute />}>
<Route path="/*" element={<AdminDashboard />} />
</Route>
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
</div>
</Router>
);
};