This is my code in App.js:
import { useRecoilValue } from 'recoil';
import { authState } from './atoms/authAtom';
import { ToastContainer } from 'react-toastify';
import { ProtectedRoute } from './layout/ProtectedRoute';
import CourseDashboard from './features/course/CourseDashboard';
import { Route, Routes } from 'react-router-dom';
import NavBar from './features/nav/Navbar';
import { LoginPage } from './features/auth/LoginPage';
export const App = () => {
const authentication = useRecoilValue(authState)
return (
<>
<ToastContainer position='bottom-right' hideProgressBar />
<NavBar />
<Routes>
<Route path='/courses' element={
<ProtectedRoute user={authentication?.user} isAuthenticated={authentication?.isAuthenticated} redirectPath={'/login'}>
<CourseDashboard />
</ProtectedRoute>
} />
<Route path='/' element={
<ProtectedRoute user={authentication?.user} isAuthenticated={authentication?.isAuthenticated} redirectPath={'/login'}>
<CourseDashboard />
</ProtectedRoute>
} />
<Route path='/login' element={<LoginPage />} />
</Routes>
</>
)
}
This is in index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './App';
import { RecoilRoot } from 'recoil';
import { BrowserRouter } from 'react-router-dom';
import 'semantic-ui-css/semantic.min.css'
import './styles.css'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RecoilRoot>
<BrowserRouter>
<App />
</BrowserRouter>
</RecoilRoot>
</React.StrictMode>
);
I am using Recoil for state management, Semantic UI React for styling and React Router DOM v6 for routing.
For some reason, the NavBar element renders at the top of the page but the components below the NavBar like the CourseDashboard or LoginPage never render.
This is my login page:
import { Container, Form, Input, Text } from "semantic-ui-react";
export const LoginPage = () => {
return (
<>
<Form>
<Input name="email" type="email" placeholder="Enter Email" />
<Input name="password" placeholder="Enter Password" type="password" />
</Form>
</>
);
};
If i comment out the semantic UI part and just use html elements like this:
import { Container, Form, Input, Text } from "semantic-ui-react";
export const LoginPage = () => {
return (
<>
{/* <Form>
<Input name="email" type="email" placeholder="Enter Email" />
<Input name="password" placeholder="Enter Password" type="password" />
</Form> */}
<h1>login</h1>
</>
);
};
it renders:
I have been banging my head for hours and couldnt find the reason. Can someone figure out whats going on? Thanks in advance.
Edit:
Taking a comment into consideration, check the DOM and looks like the LoginPage component renders, but for some reason its behind the NavBar component although they are separate components. Any idea how to separate them and render the LoginPage component below the NavBar?
This is the NavBar Component:
import React from "react";
import { Menu, Container } from "semantic-ui-react";
import { useRecoilValue } from "recoil";
import { authState } from "../../atoms/authAtom";
import { NavLink } from "react-router-dom";
import { SignedInMenu } from "./SignedInMenu";
export default function NavBar() {
const authentication = useRecoilValue(authState);
console.log(authentication);
return (
<Menu inverted fixed="top">
<Container>
<Menu.Item as={NavLink} exact to="/" header>
<img
src="/assets/logo.jpg"
alt="logo"
style={{ marginRight: "15px" }}
/>
Bhaktivedanta Vedic Academy
</Menu.Item>
<Menu.Item name="Courses" as={NavLink} to="/courses" />
{authentication?.isAuthenticated && <SignedInMenu />}
</Container>
</Menu>
);
}
The NavBar
component uses fixed positioning which takes it out of the DOM layout flow and the other elements render underneath it starting from the top of the view. You could solve this by adding padding-top
to each routed component you are rendering, or as a more trivial solution, via a layout route component that renders NavBar
and an Outlet
into a div
element that applies the padding-top
CSS rule. The NavBar
is about 44px tall, so anything around this value will be enough.
Example:
import { Outlet } from "react-router-dom";
import NavBar from "./features/nav/NavBar";
const AppLayout = () => (
<div className="app-layout">
<NavBar />
<Outlet />
</div>
);
<Routes>
<Route element={<AppLayout />}> // <-- Layout wraps all routes
<Route
element={
<ProtectedRoute
user={authentication?.user}
isAuthenticated={authentication?.isAuthenticated}
redirectPath={"/login"}
/>
}
>
<Route path="/courses" element={<CourseDashboard />} />
<Route path="/" element={<CourseDashboard />} />
</Route>
<Route path="/login" element={<LoginPage />} />
</Route>
</Routes>
.app-layout {
padding-top: 3.25rem; /* 45px from base 14px font size */
}