[英]React.js private route related issue when trying to signup or login
I am getting this error "Cannot update a component ( BrowserRouter
) while rendering a different component ( Login
). To locate the bad setState() call inside Login
" whenever I try to signUp or log in. I think this is occurring because of react router.每当我尝试注册或登录时,我都会收到此错误“无法更新组件(
BrowserRouter
),同时呈现不同的组件( Login
)。要在Login
中找到错误的 setState() 调用”。我认为这是由于反应而发生的路由器。 But i couldn't find where I messed up.但是我找不到我搞砸的地方。 Here is the code (index.js).
这是代码(index.js)。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>
);
reportWebVitals();
Here is App.js这是 App.js
import "./App.css";
import Header from "./Components/Shared/Header/Header";
import "bootstrap/dist/css/bootstrap.min.css";
import Footer from "./Components/Shared/Footer/Footer";
import { Route, Routes } from "react-router-dom";
import Home from "./Components/Pages/Home/Home";
import Login from "./Components/Pages/Login/Login";
import Register from "./Components/Pages/Login/Register";
import Contact from "./Components/Pages/Contact/Contact";
import NotFound from "./Components/Pages/NotFound/NotFound";
import Blogs from "./Components/Pages/Blogs/Blogs";
import Manage from "./Components/Pages/Manage/Manage";
import Add from "./Components/Pages/Add/Add";
import Myitems from "./Components/Pages/Myitems/Myitems";
import SingleInventory from "./Components/Pages/SingleInventory/SingleInventory";
import RequireAuth from "./Components/RequireAuth";
function App() {
return (
<div>
<Header></Header>
<Routes>
<Route path="/" element={<Home></Home>}></Route>
<Route
path="/products/:id"
element={
<RequireAuth>
<SingleInventory></SingleInventory>
</RequireAuth>}
></Route>
<Route path="/manage" element={<Manage></Manage>}></Route>
<Route path="/add" element={<Add></Add>}></Route>
<Route path="/myitems" element={<Myitems></Myitems>}></Route>
<Route path="/blogs" element={<Blogs></Blogs>}></Route>
<Route path="/contact" element={<Contact></Contact>}></Route>
<Route path="/login" element={<Login></Login>}></Route>
<Route path="/register" element={<Register></Register>}></Route>
<Route path="*" element={<NotFound></NotFound>}></Route>
</Routes>
<Footer></Footer>
</div>
);
}
export default App;
Here Login.js这里登录.js
import { Icon } from "@iconify/react";
import React, { useState } from "react";
import { Button, Form } from "react-bootstrap";
import {
useSignInWithEmailAndPassword,
useSignInWithFacebook,
useSignInWithGoogle,
} from "react-firebase-hooks/auth";
import { Link, useLocation, useNavigate } from "react-router-dom";
import auth from "../../../firebase.init";
import logo from "../../../images/login.svg";
const Login = () => {
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname || "/";
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [signInWithEmailAndPassword, user, loading, error] =
useSignInWithEmailAndPassword(auth);
const [signInWithGoogle, gUser, gLoading, gError] = useSignInWithGoogle(auth);
const [signInWithFacebook, fbUser, fbLoading, fbError] =
useSignInWithFacebook(auth);
const handleFormSubmit = (e) => {
e.preventDefault();
signInWithEmailAndPassword(email, password);
};
const handleGoogleLogin = () => {
signInWithGoogle();
};
const handleFbLogin = () => {
signInWithFacebook();
};
if (user || fbUser|| gUser) {
navigate(from, { replace: true });
}
return (
<div style={{ minHeight: "100vh" }} className="d-flex">
<div className="w-50 border border-1 d-flex align-items-center justify-content-center bg-
warning">
<img className="w-50" src={logo} alt=""/>
</div>
<div className="w-50 d-flex align-items-center justify-content-center ">
<div className="w-75 border border-1 p-5">
<h1 className="d-inline-block pb-2 mb-4 border-1 border-dark border-bottom">
Log in
</h1>
<Form className=" mx-auto" onSubmit={handleFormSubmit}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
name="email"
placeholder="Enter email"
onBlur={(e)=>setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
name="password"
placeholder="Password"
onBlur={(e)=>setPassword(e.target.value)}
/>
</Form.Group>
<p className="text-end">Forget password</p>
<Button className="w-100" variant="primary" type="submit">
Log in
</Button>
</Form>
<p className="text-center">
Don't have an account?
<Link className="text-decoration-none" to="/register">
Sign Up
</Link>
</p>
<div className="text-center ">
<Icon onClick={handleGoogleLogin} icon="logos:google-icon" />
<Icon
onClick={handleFbLogin}
className="text-primary"
icon="fa6-brands:facebook"
/>
<Icon icon="logos:github-icon" />
</div>
</div>
</div>
</div>
);
};
export default Login;
It's because you try to navigate out in the open within the Login component.这是因为您尝试在登录组件中打开导航。
if (user || fbUser|| gUser) {
navigate(from, { replace: true });
}
By invoking navigate here, you're causing an update in the navigation context, which in turn can trigger a rerender while Login is still rendering.通过在此处调用 navigate,您将在导航上下文中进行更新,这反过来会在 Login 仍在呈现时触发重新呈现。 To avoid this, you want to use a
useEffect
hook so that this is checked after the first render/as a side effect.为避免这种情况,您需要使用
useEffect
挂钩,以便在第一次渲染后检查它/作为副作用。
Wrap it in a useEffect to only navigate when one of those values changes:将其包装在 useEffect 中,以便仅在其中一个值发生变化时进行导航:
useEffect(() => {
navigate(from, { replace: true });
}, [user, fbUser, gUser]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.