[英]React Router Redirect does not render the component
這是我的 App.js:
function App() {
return (
<BrowserRouter>
<AuthProvider>
<Switch>
<PrivateRoute path="/" component={MainPage} />
<PrivateRoute path="/admin" component={MainPage} />
<Container
className="d-flex align-items-center justify-content-center"
style={{ minHeight: "100vh" }}
>
<div className="w-100" style={{ maxWidth: "400px" }}>
<Route path="/signup" component={Signup} />
<Route path="/login" component={Login} /> //The component part
<Route path="/forgot-password" component={ForgotPassword} />
</div>
</Container>
</Switch>
</AuthProvider>
</BrowserRouter>
);
}
來自 firebase 的 PriveRoute 組件的身份驗證上下文:
export default function PrivateRoute({ component: Component, ...rest }) {
const { currentUser } = useAuth();
return (
<Route
render={(props) => {
return currentUser ? <Admin {...props} /> : <Redirect to="/login" />; // it redirects when the user does not log in.
}}
></Route>
);
登錄組件:
export default function Login() {
const emailRef = useRef();
const passwordRef = useRef();
const { login, currentUser } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const history = useHistory();
if (currentUser) {
history.push("/admin/mainpage");
}
async function handleSubmit(e) {
e.preventDefault();
try {
setError("");
setLoading(true);
await login(
emailRef.current.value + "@myosmail.com",
passwordRef.current.value
);
history.push("/admin/mainpage");
} catch {
setError("Failed to log in");
}
setLoading(false);
}
return (
<>
<Card>
<Card.Body>
<h2 className="text-center mb-4">Log In</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email">
<Form.Label>Username</Form.Label>
<Form.Control ref={emailRef} required />
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required />
</Form.Group>
<Button disabled={loading} className="w-100" type="submit">
Log In
</Button>
</Form>
<div className="w-100 text-center mt-3">
<Link to="/forgot-password">Forgot Password?</Link>
</div>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Need an account? <Link to="/signup">Sign Up</Link>
</div>
</>
);
}
如果用戶沒有登錄,我想構建一個組件,它無法訪問我的 web 站點的內容,所以我構建了上面的組件。 但問題是,當我打開我的頁面並且沒有登錄時,頁面將我重定向到“/login”,但沒有呈現登錄組件,我不明白問題出在哪里。 我調試了我的組件,我看到我的代碼首先轉到 PrivateRoute 組件,然后它重定向到“/ login”,但是當頁面重定向到 Login 時沒有呈現任何內容。 當我從 App.js 中刪除 PrivateRoutes 時,我的代碼工作正常。
我的猜測是您首先在Switch
組件中放置了一個“/”路徑:
<PrivateRoute path="/" component={MainPage} />
重定向到“/login”有效,但Switch
匹配“/”部分並嘗試再次呈現此私有路由。
您的私有路由也格式不正確,它不會傳遞收到的所有Route
道具。
修復私有路由組件以傳遞所有道具。
export default function PrivateRoute({ component: Component, ...rest }) {
const { currentUser } = useAuth();
return (
<Route
{...rest}
render={(props) => {
return currentUser ? <Admin {...props} /> : <Redirect to="/login" />;
}}
/>
);
}
在Switch
組件路徑順序和特異性問題中,您希望在不太具體的路徑之前排序更具體的路徑。 “/”是所有路徑的路徑前綴,因此您希望在其他路徑之后使用它。 嵌套路由也需要在Switch
中呈現,因此只返回和呈現一個匹配項。
<BrowserRouter>
<AuthProvider>
<Switch>
<Container
className="d-flex align-items-center justify-content-center"
style={{ minHeight: "100vh" }}
>
<div className="w-100" style={{ maxWidth: "400px" }}>
<Switch>
<Route path="/signup" component={Signup} />
<Route path="/login" component={Login} /> //The component part
<Route path="/forgot-password" component={ForgotPassword} />
</Switch>
</div>
</Container>
<PrivateRoute path={["/admin", "/"]} component={MainPage} />
</Switch>
</AuthProvider>
</BrowserRouter>
不過,我對您的私有路由感到有些困惑,您在component
道具上指定了MainPage
組件,然后在其中渲染了一個Admin
組件。 通常,一個更不可知的PrivateRoute
組件可能看起來更像:
const PrivateRoute = props => {
const { currentUser } = useAuth();
return currentUser ? <Route {...props} /> : <Redirect to="/login" />;
}
這允許您使用所有正常的Route
組件道具,並且不限於僅使用component
道具。
用途:
<PrivateRoute path="/admin" component={Admin} />
<PrivateRoute path="/admin" render={props => <Admin {...props} />} />
<PrivateRoute path="/admin"> <Admin /> </PrivateRoute>
我也遇到過同樣的問題。 這解決了我。 用 Switch 包裹您的三個路線。
<Switch>
<Route path="/signup" component={Signup} />
<Route path="/login" component={Login} />
<Route path="/forgot-password" component={ForgotPassword} />
</Switch>
由於第一個私有路由有根路徑,它總是 go 到路由。 您可以將精確用於第一條私有路由。 但最好的方法應該是放置第一條私人路線
<PrivateRoute path={["/admin", "/"]} component={MainPage} />
在底部。 因此,當沒有匹配時,它只會去那里。
您沒有將路徑傳遞到ProtectedRoute
中的Route
。
<Route
{...rest} // spread the test here
render={(props) => {
return currentUser ? <Admin {...props} /> : <Redirect to="/login" />; // it redirects when the user does not log in.
}}
></Route>
還像@Drew Reese 提到的那樣切換路徑的路線。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.