skip to Main Content

I’m trying to integrate React-Admin AdminDashboard component into a larger React application that uses React-Router for navigation. However, I’m encountering issues where AdminDashboard doesn’t render or work as expected.

When I initially had the AdminDashboard directly in App.js, everything functioned correctly, and the URL displayed as "http://localhost:3000/AdminDashboard/#/users". However, after refactoring AdminDashboard into a separate component, the page fails to load, and the URL changes unexpectedly to "http://localhost:3000/users" or "http://localhost:3000/posts" as comes first in Resources.

This issue began only after moving the AdminDashboard code into its own component, indicating a potential problem with how the routing or component integration is handled.

I first made the app like Blog.logrocket

Before refactoring AdminDashboard.jsx wasn’t a separate component and it was inside app.js like the code down below:

//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

Below is my latest code setup and its not working:

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();
};

My latest code structure :

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

I’ve examined the routing setup, and while I initially believed it wasn’t the issue, I’m starting to suspect it might be related to the problem after all, given my current understanding.

Extra code and info:

the link in header:

  <Link to="/AdminDashboard">
    AdminDashboard
  </Link>
</>

Part of client-side package.json:

"proxy": "http://localhost:5000",
"dependencies": {
  "react": "^18.2.0",
  "react-admin": "^4.16.4",
  "react-dom": "^18.2.0",

Part of servier-side 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""
}, 

2

Answers


  1. With a URL like "http://localhost:3000/AdminDashboard/#/users" implies you were previously using hash routing. The app was served/hosted from "http://localhost:3000/AdminDashboard/#" and the accessible routes were:

    • "/" root/home page
    • "/users" users page
    • "/posts" posts page

    You then added client-side routing, e.g. react-router-dom and use a BrowserRouter. It seems the BrowserRouter thinks it is running from "http://localhost:3000", so the same routes above work relative to this. I suspect you could just add a basename prop to the router and edit the "admin dashboard" to omit the path prefix. This configures the router to run under a specific basename in the URL.

    Example:

    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>
      );
    };
    
    Login or Signup to reply.
  2. Have you tried setting the <Admin basename> prop as explained in the Using React-Admin in a route section?

    By this way, react-admin will include the basename in all links.

    Something like:

    const AdminDashboard = () => (
      <Admin basename="/AdminDashboard">
        // ... 
      </Admin>
    );
    
    const App = () => {
        return (
            <Router>
                <div className="App">
                    <Routes>
                        <Route path="/">
                            // ...
                            <Route
                                path="/AdminDashboard/*"
                                element={<AdminDashboard />}
                            />
                        </Route>
                    </Routes>
                </div>
            </Router>
        );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search