Here is my code, I am completely new to front end development can any one help me solve the issue, I want the user to be redirected to the login page if the user is not logged in but once he is logged in every thing should work fine but even when I click sign in, the login page shows up when I change the URL, The login page is appearing on every URL
Here's my code (i am new to front end pls dont judge)
import { useState } from 'react'
import { Route, Switch} from 'react-router-dom'
import Dashboard from "./pages/Dashboard";
import DatasetGenerator from "./pages/DatasetGenerator"
import Simulator from "./pages/Simulator"
function App() {
const [login, setlogin] = useState(true)
const [homepage, setHomepage] = useState(false)
const loginHandler = ()=>{
if(login == true){setlogin(false)
setHomepage(true)}
}
return (
<div>
{login && <SignIn loginHandler={loginHandler} />}
<Switch>
<Route path='/' exact>
{homepage && <Dashboard />}
</Route>
<Route>
{homepage && <DatasetGenerator path="/dataset-generator"/>}
</Route>
<Route path="/simulator">
{homepage && <Simulator />}
</Route>
</Switch>
</div>
)
}
export default App;
Seems like you want to conditionally render the login component OR the rest of your app. Since the login state and the homepage state appear to be mutually exclusive you probably don't need both (though perhaps we're missing some context).
return (
<div>
{login ? (
<SignIn loginHandler={loginHandler} />
) : (
<Switch>
<Route path='/' exact>
<Dashboard />
</Route>
<Route>
<DatasetGenerator path="/dataset-generator"/>
</Route>
<Route path="/simulator">
<Simulator />
</Route>
</Switch>
)}
</div>
)
A better solution would be to implement an auth workflow by creating authenticated route components that handle redirecting to a login route if not authenticated, otherwise allows the user to access the route.
Related
I have an authentication system, and I want to show different <Routes> with different available paths considering from login state.
I uesd <Navigate/> element for redirection from hidden pages depending login state. But there is a problem. <Navigate/> redirects without considering the state.
For example, when I logged in and try to open Login page I must redirects to a Main page, and when I don't logged in and try to open profile I must redirect to Login Page. And when I try to open any of this pages I automaticly redirects to Main page.
routes.jsx:
import React from 'react';
import {
Routes,
Route,
Navigate
} from 'react-router-dom';
import Profile from './pages/Profile/Main/Profile';
import Login from './pages/Auth/Login/Login';
import Register from './pages/Auth/Register/Register';
import Main from './pages/Main/Main';
import { Loans } from './pages/Profile/Active/Loans';
import ErrorPage from './pages/errorPage/ErrorPage';
export const useRoutes = isAuthenticated => {
if(isAuthenticated){
return (
<Routes>
<Route path='/profile' exact>
<Route index path=":id" element={<Profile/>}/>
<Route path="loans" element={<Loans/>} exact/>
</Route>
<Route path='/' exact element={<Main/>}/>
<Route
path="*"
element={<ErrorPage/>}
/>
<Route
path="/auth/*"
element={<Navigate to="/" replace />}
/>
</Routes>
);
} else {
return (
<Routes>
<Route path='/auth' exact>
<Route path='login' element={<Login/>} exact />
<Route path="register" exact element={<Register/>}/>
<Route
path=""
element = {
<Navigate to="login" replace />
}
/>
</Route>
<Route path='/' exact element={<Main/>}/>
<Route
path="/profile/*"
element={<Navigate to="/auth/login" replace />}
/>
<Route
path="*"
element={<ErrorPage/>}
/>
</Routes>
)
}
}
App.jsx:
import {
BrowserRouter
} from 'react-router-dom';
import {useRoutes} from './routes';
import 'materialize-css';
import { useAuth } from './hooks/auth.hook';
import { AuthContext } from './context/auth.context';
function App() {
const {token, userId, login, logout} = useAuth();
const isAuthenticated = !!token;
const routes = useRoutes(isAuthenticated);
return (
<AuthContext.Provider value = {{
token, login, logout, userId, isAuthenticated
}}>
<BrowserRouter>
<div className="container">
{routes}
</div>
</BrowserRouter>
</AuthContext.Provider>
);
}
export default App;
One issue that may be causing this is you check authentication based on whether the token exists. Debug the output of that variable to see if it is cleared correctly when you log out. Next, you are determining authentication once inside of App(), fetching the routes from useRoutes(), and then rendering the app without ever checking again if the authentication is still valid. A better approach would be something like this:
const auth = useAuth();
return ({auth.isAuthenticated ? (
<Fragment>
<Link to="/account">Account ({auth.user.email})</Link>
<Button onClick={() => auth.signout()}>Signout</Button>
</Fragment>
) : (
<Link to="/signin">Signin</Link>
)});
I created my page routing with react-router v5 and everything works well. If I click on the link, it takes me to the page, but when I reload the page I get a "404 | Page Not Found" error on the page.
import React, { useEffect, useState } from 'react'
import Home from './dexpages/Home'
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
import Dashboard from './dexpages/dashboard';
import Swapping from './dexpages/swapping'
import Send from './dexpages/send';
import Airdrops from './dexpages/airdrops'
function Main() {
const [mounted, setMounted] = useState(false)
useEffect(() => {
if (typeof window !== "undefined") {
setMounted(true)
}
}, [])
return (
<>
{mounted &&
<BrowserRouter>
<div className="min-h-screen" style={{ overflowX: 'hidden' }}>
<Routes>
<Route path="/airdrops" element={<Airdrops />} />
<Route path="/send" element={<Send />} />
<Route path="/swap" element={<Swapping />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/" element={<Home />} />
</Routes>
</div>
</BrowserRouter>
}
</>
)
}
export default Main;
This is my Main Component where I create all the routing.
This is the error I'm getting when I reload the page
Don't use React Router with next.js.
Next.js has its own routing mechanism which is used for both client-side routing and server-side routing.
By using React Router, you're bypassing that with your own client-side routing so when you request the page directly (and depend on server-side routing) you get a 404 Not Found.
Next.js has a migration guide.
Your paths need to be adjusted. For the home page it is fine to be routed to / however for the other pages there is no need for a backslash, remove the backslash from the Airdrops, Send, Swapping, and Dashboard paths respectively and you should be fine.
Try this below for each of the routes.
<Route path="airdrops" element={<Airdrops />} />
<Route path="send" element={<Send />} />
<Route path="swap" element={<Swapping />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="/" element={<Home />} />
My user variable is defined after the component mounts after signing up or logging in but when navigating to another page it is null. I have this as the AuthContext component after the user signs in.
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user=>{
setCurrentUser(user);
})
{console.log(currentUser)}
return unsubscribe
})
const value = {
signup,
currentUser,
logout,
authError,
login
}
return(
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
This is my App.js Component.
function App() {
return (
<Router>
<div className = "App">
<AuthProvider>
<Routes>
<Route path="/" element={<Home/>}/>
<Route element= {<AuthRoute/>}>
{/*
If user is already signed in re-direct to home
*/}
<Route exact path = "/sign_up" element = {<SignUp/>} />
<Route exact path = "/login" element= {<SignIn/>}/>
</Route>
<Route exact path="/new_post" element ={<AuthRouteIfLoggedOut>
<SignUp/>
</AuthRouteIfLoggedOut>}/>
<Route exact path="/about" element={<About/>}/>
</Routes>
</AuthProvider>
</div>
</Router>
);
}
AuthContext is my context component.
Any reason why when I try to navigate to another page the user is undefined or is "signed-out" on that page only? But when I navigate back to my main page it is logged in and works properly. Any reason why when navigating to different pages currentUser is null?
You have to cache user and provider logic for your routes. Here is an example Authetication in React
So I'm using react router v6 in my React App.
I have the following routes enabled in my app.js file
<Routes>
<Route path='/' component={<Home />} />
<Route path='/login' component={<SignUp />} />
<Route path='/signup' component={<Login />} />
</Routes>
Everything's fine and that. What I want to to do is to put restriction on pages. Now I know how to create PrivateRoutes and PublicRoutes based on LoggedIn User.
For this purpose I want the user to not be able to access Homepage after he or she signups.
Are there an functions for that or what strategy would I use.
I accomplished this using 'react-router-dom' and creating a PrivateRoute component. The following code is not tested but can give you some ideas. LoaderComponent is a loading animation of your choice can be toher component as well.
// Based on https://reactrouter.com/web/example/auth-workflow
// If the user is not yet authenticated.
const PrivateRoute: React.FC<PrivateRouteProps> = ({ children, path, ...props }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
//put your authentication logic
setIsAuthenticated(true);
}, []);
return (
<Route
path={path}
{...props}
render={() => (isAuthenticated ? children : <LoaderComponent />)}
/>
);
};
And in your router config
import { Switch } from 'react-router-dom';
<Switch>
<PrivateRoute exact path='/'>
<Home />
</PrivateRoute>
...
</Switch>
As I am new on ReactJS. I tried many solutions to implement the show/hide side menu on different components.
Requirement is:
a. When user is logged in then side menu shows on all components.
b. When user is logged out then It shows only some of the components like Forgot Password or Terms and condition(menus name changed as per the authentication) but hides on Login Component.
App.js
<Router>
<SideNavigation />
<Routes />
</Router>
Routes.js
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/forgotPassword" component={ForgotPassword} />
<Route exact path="/termAndCondition" component={TermAndCondition} />
<PrivateRoutes exact path="/" component={Dashboard} />
<PrivateRoutes exact path="/emp" component={Employee} />
<PrivateRoutes exact path="/empList" component={EmployeeList} />
</Switch>
Use a simple state variable and keep track of the login status in your App.js. (for example - by useState() hook below👇)
const [isLoggedIn, setIsLoggedIn] = useState(false);
Pass a callback function to the Routes component and then to the Login Component.
<Routes onLogIn={()=>setIsLoggedIn(true)}/>
Routes.js Assuming it's a functional component (use this.props for class component).
<Route exact path="/login" >
<Login onLogIn={props.onLogIn}/>
</Route>
You can then call the onLogIn() function from the Login component and update the state.
Now, again in App.js -
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [canShowNav, setCanShowNav] = useState(false);
const [currentComponent, setCurrentComponent] = useState(''); //default component shown
useEffect(()=>{ //for determining canShowNav's value
if(isLoggedIn)setCanShowNav(true)
else{
if(currentComponent === 'login'){ //add any other components you want where nav should not be shown
setCanShowNav(false)
}
else setCanShowNav(true)
}
}, [isLoggedIn, currentComponent])
return(
<Router>
{canShowNav && <SideNavigation onComponentChange={(component)=>setCurrentComponent(component)}/>}
<Routes onComponentChange={(component)=>setCurrentComponent(component)} onLogIn={()=>setIsLoggedIn(true)}/>
</Router>
)
Then call onComponentChange("componentName") from the SideNavigation whenever a link is clicked, passing the component's name which is clicked.
You can pass the onComponentChange function to the login page too, to change the state when user clicks on Forgot Password or anything like that and update the state.
Routes.js
<Route exact path="/login" >
<Login onLogIn={props.onLogIn} onComponentChange={props.onComponentChange}/>
</Route>
Let me know if it helps you or not!✌