React-router-dom navigate not rendering page - reactjs

I am working on an app using useNavigate to go from page to page but am having trouble. Currently, the button click will cause the url to update, but the corresponding page doesn't render. Any help as to what I'm doing wrong?
Here is my button component:
import Fab from '#material-ui/core/Fab';
import AddIcon from '#mui/icons-material/Add';
import { useNavigate } from "react-router-dom";
const FabButton = () => {
let navigate = useNavigate();
return (
<div >
<Fab
onClick={() => navigate(`/add`)}>
<AddIcon />
</Fab>
</div>
)
};
export default FabButton;
My App.js:
import React from 'react';
import { Router, Routes, Route } from 'react-router-dom';
import history from '../history';
import AddPage from './AddPage';
import HomePage from './HomePage';
class App extends React.Component {
render() {
return (
<Router location={history.location} navigator={history} >
<Routes >
<Route exact path="/add" element={ <AddPage title="One Rep - Add" /> } ></Route>
<Route exact path="/" element={ <HomePage title="One Rep - Home" /> } ></Route>
</Routes>
</Router>
)
}
};
export default App;
My history.js:
import { createHashHistory } from 'history';
export default createHashHistory();
My AddPage.js:
export default AddPage;
import React, { useState } from 'react';
import Header from '../components/Header';
import { makeStyles } from '#material-ui/core/styles';
import { TextField, Button, InputAdornment } from '#material-ui/core';
const AddPage = () => {
const [moveData, setMoveData] = useState({ movementName:'', movementWeight: '' });
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div>
<Header title={"Add Movement"} />
<div>
<form onSubmit={handleSubmit} >
<div>
<TextField
name="movementName"
variant="outlined"
label="Movement Name"
style={{ width:200 }}
value={moveData.movementName}
onChange={(e) => setMoveData({ ...moveData, movementName: e.target.value })}
/>
<TextField
name="movementWeight"
variant="outlined"
label="One Rep Max"
style={{ width:200 }}
value={moveData.movementWeight}
InputProps={{endAdornment: <InputAdornment position="end">lb</InputAdornment>}}
onChange={(e) => setMoveData({ ...moveData, movementWeight: e.target.value })}
/>
</div>
<div>
<Button
variant="contained"
type="submit"
fullWidth >
Submit
</Button>
</div>
</form>
</div>
</div>
);
};
export default AddPage;
I am using react-router-dom ^6.3.0

In react router v6+ you should use BrowserRouter instead of Router. You can see an example in their documentation
So, in your case it should look like this
<BrowserRouter>
<Routes>
<Route
exact
path="/add"
element={<AddPage title="One Rep - Add" />}
></Route>
<Route
exact
path="/"
element={<HomePage title="One Rep - Home" />}
></Route>
</Routes>
</BrowserRouter>
Here is minimal reproduction

Related

I can route into my components with their respective path name, so my login page doesn't make any sense

I need help!!!
I have multiple content that is to be rendered after login. I have successfully created the login page and it is working fine.
but i can render the components just by typing the path name in the url bar of my browser so my login page doesn't make any sense.
i have {dashboard, History , employee }
i can just render these components by typing /dashboard, /history without logging in
which should not work like that
THis is my Login.jsx
import React, { useEffect, useState } from "react";
import "./Login.css";
import logo from "../../../Icons/logo.png";
import { useNavigate, useParams, NavLink } from "react-router-dom";
import axios from "axios";
function Login({ setusers }) {
const history = useNavigate();
const [user, setUser] = useState({
userName: "",
password: "",
});
const handlechange = (e) => {
const { name, value } = e.target;
setUser({
...user,
[name]: value,
});
};
const login = () => {
axios.post("/login", user).then((res) => {
alert(res.data.message);
setusers(res.data.user);
history.push("/dashboard")
});
};
return (
<>
<div className="tskms_login-container">
<div className="tskms_login-container-left">
<img src={logo} alt="logo" />
</div>
<div className="tskms_login-container-right">
<p>Login</p>
<form>
<input
type="text"
name="userName"
value={user.userName}
onChange={handlechange}
placeholder="Username"
/>
<input
type="password"
name="password"
value={user.password}
onChange={handlechange}
placeholder="Password"
/>
<h5>Forgot Password?</h5>
{/* <NavLink to={"/dashboard"}> */}
</form>
<button className="tskms_login-right-btn" onClick={login}>
Login
</button>
<div></div>
{/* </NavLink> */}
</div>
</div>
</>
);
}
export default Login;
this is my app.js
import "./App.css";
import { Routes, Route, useNavigate, Navigate } from "react-router-dom";
import Dashboard from "./Components/After Login/Dashboard/Dashboard";
import Task from "./Components/After Login/Task/Task";
import Employee from "./Components/After Login/Employee/Employee";
import History from "./Components/After Login/History/History";
import Notification from "./Components/After Login/Notification/Notification";
import Popup from "./Components/After Login/Task/Popup";
import Addemploye from "./Components/After Login/Employee/Addemploye";
import EmployeeCard from "./Components/After Login/Employee/EmployeeCard";
import Login from "./Components/Before Login/Login/Login";
import { useState } from "react";
function App() {
const [user, setusers] = useState({});
return (
<>
<Routes>
<Route
path="/"
element={
user && user._id ? <Navigate to="/dashboard" /> : <Login setusers={setusers} />
}
/>
<Route path="/login" element={<Login setusers={setusers} />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/task" element={<Task />} />
<Route path="/createtask" element={<Popup />} />
<Route path="/employee" element={<Employee />} />
<Route path="/history" element={<History />} />
<Route path="/notification" element={<Notification />} />
<Route path="/employee" element={<Addemploye />} />
<Route exact path="/employee/:id" element={<EmployeeCard />} />
</Routes>
</>
);
}
export default App;
You can add HOC component, which will detect if there is authz token. If there is not, you can display information like: 'You need to be logged in to enter this page'.
For example:
export default withDashboardHocs(Dashboard)
And HOC component would look like:
export default function withDashboardHocs<C>(
WrappedComponent: React.ComponentType<C>,
redirect = '/login'
) {
return (props: C) => {
const router = useRouter();
const [authzResult] = "API WITH AUTHZ TOKEN"();
const { data, fetching, error } = authzResult;
if (error) {
router.push(redirect);
}
if (fetching) {
return null;
}
if (!data) {
return null;
}
const whoAmI = data.AuthWhoAmI;
return (
<UserContext.Provider value={whoAmI}>
<WrappedComponent {...props} />
</UserContext.Provider>
);
};
}

`No routes matched location "/" ` warning shown on the console

I am trying to implement a small project and got an error/warning like above title.
Here is my Index.jsx:
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { BrowserRouter} from "react-router-dom";
import { App } from "./components/app";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<Suspense fallback={<div>Loading...</div>}>
<BrowserRouter>
<App />
</BrowserRouter>
</Suspense>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
App.jsx:
import React, { useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { Container } from "#material-ui/core";
import { ToastContainer } from "react-toastify";
import { Route, Routes } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import Sidebar from "../sidebar/Sidebar";
import TopNav from "../topnav/TopNav";
import { AppRoutes } from "../AppRoutes";
import ThemeAction from "../../store/actions/ThemeAction";
import "./App.scss";
const useStyles = makeStyles({
contentStyle: {
margin: "30px auto",
},
});
export const App = () => {
const themeReducer = useSelector((state) => state.ThemeReducer);
const classes = useStyles();
const dispatch = useDispatch();
useEffect(() => {
const themeClass = localStorage.getItem("themeMode", "theme-mode-light");
const colorClass = localStorage.getItem("colorMode", "theme-mode-light");
dispatch(ThemeAction.setMode(themeClass));
dispatch(ThemeAction.setColor(colorClass));
}, [dispatch]);
return (
<Routes>
<Route
render={(routeProps) => (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
)}
/>
</Routes>
);
};
And AppRoutes.jsx:
import React from "react";
import { Route, Routes } from "react-router-dom";
import Customers from "../pages/Customers";
import { Dashboard } from "../pages/Dashboard";
import { UserLogin } from "./User/Login";
import { UserSignup } from "./User/Signup/UserSignup";
export const AppRoutes = () => {
return (
<Routes>
<Route index path="/" element={<Dashboard />} />
<Route path="customers" component={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>
);
};
And the project is not running) I mean white blank on browser window while there is no error except index.tsx:25 No routes matched location "/" .
In react-router-dom#6 there are no longer any render (or component or children function props). Remove the Routes and Route component in App. You will also update Sidebar to access the location object via hook.
App
return (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
);
Sidebar
const Sidebar = () => {
const location = useLocation();
const activeItem = sidebar_items.findIndex(
(item) => item.route === location.pathname
);
return (
<div className="sidebar">
<div className="sidebar__logo">
<img src={logo} alt="company logo" />
</div>
{sidebar_items.map((item, index) => (
<Link to={item.route} key={index}>
<SidebarItem
title={item.display_name}
icon={item.icon}
active={index === activeItem}
/>
</Link>
))}
</div>
);
};
AppRoutes
Remove the index prop from the "/" route. When you specify an index route the path prop is ignored. Also, make sure all the routes are correctly using the element prop.
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="customers" element={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>

react: React-router Link not loading a component

I have a login page which has a forgot password link and it takes the user to forgot password page.
When I click on the forgot password link, it changes the URL but does not load the component.
Code for login page
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
// assets
import Logo from "../../../assets/images/kvh-logo.svg";
import bgImgArray from "../../../assets/images/bg";
import { Button, Form, Input, InputGroup, InputGroupAddon } from "reactstrap";
import "./Login.css";
const Login = (props) => {
const [loading, setLoading] = useState(false);
const userid = useFormInput("");
const password = useFormInput("");
const [error, setError] = useState(null);
// for changing backgrounds
const [index, setIndex] = useState(0);
return (
<div className="container-fluid backgroundContainer">
<div className="Login">
<div className="login-form-container">
<div className="logo">
<img src={Logo} className="App-logo" alt="logo" />
</div>
<div className="content">
<Form className="login-form">
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-user"></i>
</InputGroupAddon>
<Input
autoFocus
type="email"
aria-label="Username"
aria-describedby="username"
aria-invalid="false"
placeholder="Username or Email"
{...userid}
/>
</InputGroup>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-lock"></i>
</InputGroupAddon>
<Input
type="password"
placeholder="Password"
aria-label="password"
aria-describedby="password"
{...password}
/>
</InputGroup>
<div className="form-actions">
{error && (
<>
<small style={{ color: "red" }}>{error}</small>
<br />
</>
)}
<br />
<Button
className="pull-right"
block="true"
type="submit"
bssize="small"
value={loading ? "Loading..." : "Login"}
onClick={handleLogin}
disabled={loading}
>
Login
</Button>
<br />
</div>
<div className="forgotPassword">
<Link to="/forgotPassword">Forgot password?</Link>
</div>
</Form>
</div>
</div>
</div>
</div>
);
};
const useFormInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const handleChange = (e) => {
setValue(e.target.value);
};
return {
value,
onChange: handleChange,
};
};
export default Login;
In routing code, I have Admin Layout which looks after the dashboard and AuthLayout which looks after the Login page.
I tried searching for the solution but unfortunately couldn't find any solutions. Hence, posting it here.
Router Code
import React from "react";
import {
BrowserRouter as Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
import { createBrowserHistory } from "history";
import AdminLayout from "layouts/Admin/Admin.js";
import AuthLayout from "layouts/Auth/Auth.js";
import ResetPassword from "../components/pages/reset-password/ResetPassword";
const hist = createBrowserHistory();
const AppRouter = () => {
return (
<Router history={hist}>
<Switch>
<Route path="/admin" render={(props) => <AdminLayout {...props} />} />
<Route path="/" render={(props) => <AuthLayout {...props} />} />
<Route path="/forgotPassword" component={ResetPassword} />
<Redirect from="/" to="/auth" />
</Switch>
</Router>
);
};
export default AppRouter;
Adding Auth Layout Code
import React from "react";
import { Route, Switch, Redirect, Link } from "react-router-dom";
import Login from "../../components/pages/login/Login";
import ResetPassword from "../../components/pages/reset-password/ResetPassword";
import routes from "routes/routes.js";
class Pages extends React.Component {
getRoutes = (routes) => {
return routes.map((prop, key) => {
if (prop.collapse) {
return this.getRoutes(prop.views);
}
if (prop.layout === "/auth") {
return (
<Route
path={prop.layout + prop.path}
component={prop.component}
key={key}
/>
);
} else {
return null;
}
});
};
getActiveRoute = (routes) => {
let activeRoute = "WATCH";
for (let i = 0; i < routes.length; i++) {
if (routes[i].collapse) {
let collapseActiveRoute = this.getActiveRoute(routes[i].views);
if (collapseActiveRoute !== activeRoute) {
return collapseActiveRoute;
}
} else {
if (
window.location.pathname.indexOf(
routes[i].layout + routes[i].path
) !== -1
) {
return routes[i].name;
}
}
}
return activeRoute;
};
componentDidMount() {
document.documentElement.classList.remove("nav-open");
}
render() {
return (
<div className="wrapper wrapper-full-page" ref="fullPages">
<div className="full-page">
<Login {...this.props}></Login>
<div className="forgotPassword">
<Link to="/forgotPassword">Forgot password?</Link>
</div>
<Switch>
{this.getRoutes(routes)}
<Redirect from="*" to="/auth/login" />
</Switch>
</div>
</div>
);
}
}
export default Pages;
look at this code that you wrote:
<Route path="/" render={(props) => <AuthLayout {...props} />} />
<Route path="/forgotPassword" component={ResetPassword} />
it's never going to /forgotPassword because path always match with first Route.
you should use exact props:
<Route exact path="/" render={(props) => <AuthLayout {...props} />} />
<Route exact path="/forgotPassword" component={ResetPassword} />
If you create your own history then you should use Router instead of BrowserRouter.
import {
Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
Because, BrowserRouter comes with its own history and you provide another one, this causes the problem.
Recently I faced this issue with React 18.
Version of react was 18.0.1 and react-router-dom was 5.1.0 so StrictMode is causing the issue
Just remove or comment the Tag <React.StrictMode> and it should work fine.
Wrap inside Router as given below.
import {
BrowserRouter as Router,
} from "react-router-dom";
<Router><Link to="/forgotPassword">Forgot password?</Link> <Router/>

How to redirect from login page to home page if the authentication success in react

I'm checking whether user is authenticated or not from service response, I want to redirect from the login page to the application home page if the authentication success. How can achieve this can anyone please suggest.
Here is the SignIn.js
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
import axios from 'axios'
import { Formik} from 'formik'
import { FormControl } from '#material-ui/core';
import { Redirect } from 'react-router-dom'
export default function SignIn(props) {
const classes = useStyles();
const [ssoId, setSsoId] = React.useState('');
const [password, setPassword] = React.useState('');
const handleSsoIdChange = (e) => {
e.preventDefault();
setSsoId(e.target.value);
}
const handlePasswordChange = (e) => {
e.preventDefault();
setPassword(e.target.value);
}
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Formik
initialValues={{ ssoId: '', password: ''}}
onSubmit={(values, {setSubmitting, resetForm})=>{
setSubmitting(true);
setTimeout(()=>{
setSsoId(values.ssoId)
setPassword(values.password)
console.log(ssoId)
console.log(password)
axios.get(`http://localhost:5000/authentication/${ssoId}/${password}`)
.then(response => {
console.log(response.data)
if(response.data === 'success'){
return <Redirect to='/admin/aboutUs/whatWeDo' />
}
else{
alert("You have entered wrong credentials")
}
})
resetForm();
setSubmitting(false)
},500)
}}>
{({ handleSubmit })=>(
<form onSubmit={handleSubmit}>
<FormControl className={classes.form}>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="ssoId"
label="SSO ID"
name="ssoId"
autoComplete="sso"
autoFocus
value= {ssoId}
onChange = {handleSsoIdChange}
/>
</FormControl>
<FormControl className={classes.form}>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
value= {password}
onChange={handlePasswordChange}
/>
</FormControl>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
</form>
)}
</Formik>
</div>
</Container>
);
}
and here is the index.js code
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { Router, Route, Switch, Redirect } from "react-router-dom";
// core components
import Admin from "layouts/Admin.js";
import SignIn from "layouts/SignIn";
const hist = createBrowserHistory();
ReactDOM.render(
<Router history={hist}>
<Switch>
<Route path="/" component={SignIn} />
<Route path="/admin" component={Admin} />
<Redirect from="/admin" to="/admin/aboutUs/whatWeDo" />
</Switch>
</Router>,
document.getElementById("root")
);
When the user authentication success the application route has to be redirected to /admin/aboutUs/whatWeDo So what is the best way to achieve this.
Ok if you want to redirect to a path that is located in your project you can do that by using this code :
onClick = () => {
if(checkAuth)
this.props.history.push('your route');
}
and if you want to redirect the user to a path that is not located in your project use this code :
onClick = () => {
if(checkAuth)
windows.location.href = 'your route'
}
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { Router, Route, Switch, Redirect } from "react-router-dom";
// core components
import Admin from "layouts/Admin.js";
import SignIn from "layouts/SignIn";
const hist = createBrowserHistory();
const loggedRoutes = () => (
<Switch>
<Route path="/" component={SignIn} />
<Route path="/admin" component={Admin} />
<Redirect from="/admin" to="/admin/aboutUs/whatWeDo" />
</Switch>
);
const routes = () => (
<Switch>
<Route path="/" component={SignIn} />
<Route path="/login" component={Admin} />
<Redirect from="/" to="/login" />
</Switch>
);
ReactDOM.render(
<Router history={hist}>
{checkIfAuth? loggedRoutes():routes()}
</Router>,
document.getElementById("root")
);
The condition checkIFAuth is the login state of your application. Maybe located in Redux or something like that.

Seriously Stuck with React Router Issue URL change but not view or Render Components || React||Redux

When I click on My some Of Links That change Urls but not change view Or not render Components, I m Using React And Redux for developing App, That issue directly effecting app. My routeJs Or Application.js File is given Below.
import React, { useEffect } from 'react';
import './App.css';
import { Router, Route, Switch } from 'react-router-dom';
import history from './history';
import Navbar from './components/layouts/Navbar';
import Landing from './components/layouts/Landing';
import Register from './components/auth/Register';
import Login from './components/auth/Login';
import Alert from './components/layouts/Alert';
import { loadUser } from './actions/auth';
import { useDispatch } from 'react-redux';
import Dashboard from './components/dashboard/Dashboard';
import CreateProfile from './components/profile-form/CreateProfile';
import EditProfile from './components/profile-form/EditProfile';
import AddEducation from './components/profile-form/AddEducation';
import AddExperience from './components/profile-form/AddExperience';
import Profiles from './components/profiles/Profiles';
import Profile from './components/profile/Profile';
import Posts from './components/posts/Posts';
import PrivateRoute from './components/routing/PrivateRoute';
const App = () => {
const dispatch = useDispatch(() => loadUser());
useEffect(() => {
dispatch(loadUser());
}, [dispatch]);
return (
<Router history={history}>
<Navbar />
<Route exact path="/" component={Landing} />
<section className="container">
<Alert />
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:id" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute exact path="/posts" component={Posts} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute exact path="/edit-profile" component={EditProfile} />
<PrivateRoute exact path="/add-education" component={AddEducation} />
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
</Switch>
</section>
</Router>
);
};
export default App;
I asked this Question Several times on Different platforms got some valuable information but that still not works. here Is one Of my Component review it's code.
import React, { useEffect, Fragment } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getCurrentUser } from '../../actions/profile';
import Spinner from '../layouts/Spinner';
import { Link, withRouter } from 'react-router-dom';
import DashboardActions from './DashboardActions';
import Experience from './Experience';
import Education from './Education';
import { deleteAccount } from '../../actions/profile';
const Dashboard = () => {
const dispatch = useDispatch(() => getCurrentUser(), () => deleteAccount());
const profileUser = useSelector(state => state.profile);
const auth = useSelector(state => state.auth);
const { profile, loading } = profileUser;
const { user } = auth;
useEffect(() => dispatch(getCurrentUser()), [dispatch]);
return loading && profile === null ? (
<Spinner />
) : (
<Fragment>
<h1 className="large text-primary">Dashboard</h1>
<p className="lead">
<i className="fa fa-user"></i>
{' '}Welcome {user && user.name}
</p>
{profile !== null ? (
<Fragment>
<DashboardActions />
<Experience experience={profile.experience} />
<Education education={profile.education} />
<div className="my-2">
<button
className="btn btn-danger"
onClick={() => dispatch(deleteAccount())}
>
Delete My Account!!!
</button>
</div>
</Fragment>
) : (
<Fragment>
<p>You have not yet setup profile, please add some info</p>
<Link to="/create-profile" className="btn btn-primary">
Create Profile
</Link>
</Fragment>
)}
</Fragment>
);
};
export default withRouter(Dashboard);
I am here to provide you About code that You need to know Kindly review this and Ans to get out this problems Thanks..

Resources