反应:反应路由器 Link 未加载组件
react: React-router Link not loading a component
我有一个 login page
,它有一个 forgot password
link,它需要用户忘记密码页面。
当我单击 forgot password
link 时,它会更改 URL 但不会加载组件。
登录页面代码
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;
在路由代码中,我有管理仪表板的管理布局和管理登录页面的 AuthLayout。
我尝试搜索解决方案,但不幸的是找不到任何解决方案。因此,将其张贴在这里。
路由器代码
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;
添加授权布局代码
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;
如果您创建自己的 history
,那么您应该使用 Router
而不是 BrowserRouter
。
import {
Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
因为 BrowserRouter
自带 history
而你又提供了一个,这就导致了问题。
如下所示在 Router 内部包装。
import {
BrowserRouter as Router,
} from "react-router-dom";
<Router><Link to="/forgotPassword">Forgot password?</Link> <Router/>
看看你写的这段代码:
<Route path="/" render={(props) => <AuthLayout {...props} />} />
<Route path="/forgotPassword" component={ResetPassword} />
它永远不会 /forgotPassword
因为路径总是与第一条路线匹配。
你应该使用 exact
道具:
<Route exact path="/" render={(props) => <AuthLayout {...props} />} />
<Route exact path="/forgotPassword" component={ResetPassword} />
我有一个 login page
,它有一个 forgot password
link,它需要用户忘记密码页面。
当我单击 forgot password
link 时,它会更改 URL 但不会加载组件。
登录页面代码
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;
在路由代码中,我有管理仪表板的管理布局和管理登录页面的 AuthLayout。
我尝试搜索解决方案,但不幸的是找不到任何解决方案。因此,将其张贴在这里。
路由器代码
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;
添加授权布局代码
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;
如果您创建自己的 history
,那么您应该使用 Router
而不是 BrowserRouter
。
import {
Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
因为 BrowserRouter
自带 history
而你又提供了一个,这就导致了问题。
如下所示在 Router 内部包装。
import {
BrowserRouter as Router,
} from "react-router-dom";
<Router><Link to="/forgotPassword">Forgot password?</Link> <Router/>
看看你写的这段代码:
<Route path="/" render={(props) => <AuthLayout {...props} />} />
<Route path="/forgotPassword" component={ResetPassword} />
它永远不会 /forgotPassword
因为路径总是与第一条路线匹配。
你应该使用 exact
道具:
<Route exact path="/" render={(props) => <AuthLayout {...props} />} />
<Route exact path="/forgotPassword" component={ResetPassword} />