在MERN堆栈中进行登录身份验证后,我的登录页面未重定向到事件页面

时间:2020-09-09 03:59:09

标签: javascript node.js reactjs express mern

当我登录我的React应用程序时。用户已成功通过身份验证,但未重定向到我的“ /事件” 页面。 当我输入用户名和密码,然后单击“提交”按钮时,它在控制台中显示为已通过身份验证。但是它没有重定向到任何地方,它在同一登录页面中。然后,当我刷新wepbage时,标题会相应更改,但它在同一登录页面中。

我不知道我的文件出了什么问题。

我的代码如下: app.js:

import React from 'react';
import './App.css';
import Header from './components/header';
import Events from './components/event';
import Signup from './components/signup';
import Login from './components/login';
import Content from './components/content';
import Footer from './components/footer';
import EventDetails from './components/eventdetails';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Switch, Route} from 'react-router-dom';


function App() {
  return (
    <Router >
      <div className="App">
        <Header/>
        <Switch>
          <Route path="/" exact render={(routeprops) => <Content {...routeprops} eventdetails={EventDetails} />}/>
          <Route path="/events" render={(routeprops) => <Events {...routeprops} eventdetails={EventDetails} />}/>
          <Route path="/signup" component={Signup}/>
          <Route path="/login" component={Login}/>
        </Switch>
        <Footer/>
      </div>
    </Router>
  );
}

export default App;

login.js:

import React from 'react';
import useForm from "./useForm";
import validate from './LoginFormValidationRules';
import Message from './message';


const Login = () => {
    const {
        values,
        errors,
        handleChange,
        handleSubmit,
        message
    } = useForm(logging, validate );

    function logging() {
        console.log('No errors, submit callback called!');
    }

    return (
        <div className="container my-container3">
            <br/><br/>
            <h2>LOGIN</h2>
            <br/>
            <form onSubmit={handleSubmit} noValidate>
                <div >
                    <label htmlFor="email">Email Address</label>
                    <div >
                        <input autoComplete="off" className={` ${errors.email && 'inputError'}`} type="email" name="email" onChange={handleChange} value={values.email || ''} required />
                        {errors.email && (
                            <p className="error">{errors.email}</p>
                        )}
                    </div>
                </div>
                <br/>
                <div>
                    <label htmlFor="password">Password</label>
                    <div >
                        <input className={` ${errors.password && 'inputError'}`} type="password" name="password" onChange={handleChange} value={values.password || ''} required />
                    </div>
                    {errors.password && (
                        <p className="error">{errors.password}</p>
                    )}
                </div>
                <br/>
                <button type="submit">Login</button>
                {message ? <Message message={message}/> : null}
                <br/>
                <hr/>
                <h6>Haven't Registered <a href="/signup">Click Here</a></h6>
            </form>
        </div>
    );
}
export default Login;

useform.js:

import {useState, useEffect, useContext } from 'react';
import AuthContext from '../context/AuthContext';
import AuthService from '../services/AuthServices';
import {useHistory} from "react-router-dom";


const useForm = (callback, validate, ) => {

  const [message,setMessage] = useState(null);
  const authContext = useContext(AuthContext);
  const [values, setValues] = useState({username:"",password:""});
  const [errors, setErrors] = useState({username:"",password:""});
  const [isSubmitting, setIsSubmitting] = useState(false);
  let history=useHistory();

  useEffect(() => {
    if (Object.keys(errors).length === 0 && isSubmitting) {
      callback();
    }
  }, [errors]);

  const handleSubmit = event => {
    if (event) event.preventDefault();
    setErrors(validate(values));
    setIsSubmitting(true);
    AuthService.login(values).then(data=>{
      const { isAuthenticated,user,message} = data;
      if(isAuthenticated){
        authContext.setUser(user);
        authContext.setIsAuthenticated(isAuthenticated);
        history.push("/events");
      }
      else
          setMessage(message);
    });
  };

  const handleChange = (event) => {
    event.persist();
    setValues(values => ({ ...values, [event.target.name]: event.target.value }));
  };

  return {
    values,
    errors,
    handleChange,
    handleSubmit,
    message
  }
};

export default useForm;

authservice.js:

export default {
    login : user =>{
        console.log(user);
        return fetch('/user/login',{
            method : "post",
            body : JSON.stringify(user),
            headers : {
                'Content-Type' : 'application/json',
                'Accept': 'application/json'
            }
        }).then(res => {
            if(res.status !== 401)
                return res.json().then(data => data);
            else
                return { isAuthenticated : false, user : {email : "",role : ""}};
        })
    },
    register : user =>{
        console.log(user);
        return fetch('/user/register',{
            method : "post",
            body : JSON.stringify(user),
            headers : {
                'Content-Type' : 'application/json',
                'Accept': 'application/json'
            }
        }).then(res => res.json())
          .then(data => data);
    },
    logout : ()=>{
        return fetch('/user/logout')
                .then(res => res.json())
                .then(data => data);
    },
    isAuthenticated : ()=>{
        return fetch('/user/authenticated')
                .then(res=>{
                    if(res.status !== 401)
                        return res.json().then(data => data);
                    else
                        return { isAuthenticated : false, user : {email : "",role : ""}};
                });
    }

}

authcontext.js:

import React, {createContext,useState,useEffect} from 'react';
import AuthService from '../services/AuthServices';

export const AuthContext = createContext();

export default ({ children })=>{
    const [user,setUser] = useState(null);
    const [isAuthenticated,setIsAuthenticated] = useState(false);
    const [isLoaded,setIsLoaded] = useState(false);

    useEffect(()=>{
        AuthService.isAuthenticated().then(data =>{
            setUser(data.user);
            setIsAuthenticated(data.isAuthenticated);
            setIsLoaded(true);
        });
    },[]);

    return (
        <div>
            {!isLoaded ? <h1>Loading</h1> : 
            <AuthContext.Provider value={{user,setUser,isAuthenticated,setIsAuthenticated}}>
                { children }
            </AuthContext.Provider>}
        </div>
    )
}

validationform.js:

export default function validate(values) {
    let errors = {};
    if (!values.email) {
      errors.email = 'Email address is required';
    } else if (!/\S+@\S+\.\S+/.test(values.email)) {
      errors.email = 'Email address is invalid';
    }
    if (!values.password) {
      errors.password = 'Password is required';
    } else if (values.password.length < 8) {
      errors.password = 'Password must be 8 or more characters';
    }
    return errors;
  };

请帮助我。我已经搜索了大约2个月,找不到。.

2 个答案:

答案 0 :(得分:1)

您需要在login.js中编写一条if语句。

if(isAuthenticated){
   return <Redirect to="/" />
 }

查看反应路由器文档

答案 1 :(得分:1)

您使用了发生错误时会触发的useEffect

 useEffect(() => {
    if (Object.keys(errors).length === 0 && isSubmitting) {
      callback();
    }
  }, [errors]);

与此类似,您可以编写一个useEffect在登录成功后触发。

添加

const [authenticated, setAuthenticated] = useState(false);

然后成功登录

if(isAuthenticated){
  setAuthenticated(true)// this should fire the useEffect

添加一个useEffect,用于检查authenticated是否为真。

  useEffect(() => {
     if (authenticated) {
     history.push("/events");
     }
     //or whatever you use like <Redirect to="/events" /> if using react router
  }, [authenticated]);

,或者您可以尝试使用user,看看在获取值时是否触发useEffect。请记住在useEffect中使用它之前先声明用户。

  let user = false;
  useEffect(() => {
     if (user) {
     history.push("/events");
    <Redirect to="/events" /> //if using react router
   }
     
  }, [user]);

如果执行此操作,则不能再将user声明为const。您将不得不为用户字段重新分配一个值,例如user = somedata you want to assign