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