React.js 尝试注册或登录时与私人路由相关的问题

React.js private route related issue when trying to signup or login

我收到此错误“无法在呈现不同组件 (Login) 时更新组件 (BrowserRouter)。要在 Login 中找到错误的 setState() 调用”每当我尝试注册或登录时。我认为这是由于反应路由器而发生的。但是我找不到我搞砸的地方。这是代码 (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();

这里是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;

这里Login.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;

这是因为您尝试在登录组件中打开导航。

if (user || fbUser|| gUser) {
 navigate(from, { replace: true });
 }

通过在此处调用导航,您将在导航上下文中进行更新,这反过来又会在登录仍在呈现时触发重新呈现。为避免这种情况,您需要使用 useEffect 挂钩,以便在第一个 render/as 副作用之后进行检查。

将其包装在 useEffect 中,以便仅在这些值之一发生变化时导航:

useEffect(() => {
 navigate(from, { replace: true });
}, [user, fbUser, gUser]);