mongodb useNavigate钩子在我的react应用中不起作用

c90pui9n  于 2023-02-08  发布在  Go
关注(0)|答案(1)|浏览(120)

我正试图开发一个页面,在注册后,你可以登录的OTP,这是要通过节点邮件模块的React。
我已经用postman API测试了我的REST API。它工作得很好。
但主要的问题是发完邮件后,我不能去其他页面。

import "../styles/mix.css";
import { Navigate, NavLink, useNavigate } from "react-router-dom";
import { useState } from "react";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { sentOtpFunction } from "../services/Apis";

export default function Login() {
  const [email,setEmail]=useState("");
const navigate=useNavigate();
  //sendOtp
  const sendOtp= async (e)=>{
    e.preventDefault();
    if(email===""){
      toast.error("Enter Your Email!");
    }
    else if(!email.includes('@')){
      toast.error("Enter Valid Email!");
    }
    else{
      const data={
        email:email
      }
      
      const response=await sentOtpFunction(data);
      console.log(response);
      if(response.status===200){
        navigate("/user/otp");
      }
      else{
        
        toast.error(response.response.data.error)
      }
    }
  }
  return (
    <>
    <section>
        <div className="form_data">
          <div className="form_heading">
            <h1>Welcome Back, Log In</h1>
            <p>Hi, we are glad you are back. Please login.</p>
          </div>
          <form>
            <div className="form_input">
              <label htmlFor="email">Email</label>
              <input type="email" name="email" onChange={(e)=>setEmail(e.target.value)} id="" placeholder="Enter your Email address"></input>
            </div>
            <button className="btn" onClick={sendOtp}>Login</button>
            <p>Don't have an account? <NavLink to="/register">Sign up</NavLink></p>
          </form>
        </div>
        <ToastContainer/>
        </section>
    </>
  )
}

这是sendOtp函数:

import {commonrequest} from './ApiCall';
import {BACKEND_URL} from './helper';

 export const registerfunction=async(data)=>{
return await commonrequest("POST",`${BACKEND_URL}/user/register`,data)
 }

 export const sentOtpFunction=async (data)=>{
    return await commonrequest("POST",`${BACKEND_URL}/user/sendotp`,data)

    }

这是我的最爱。js:

import axios from 'axios';

export const commonrequest= async(methods,url,body,header)=>{
       let config={
        method: methods,
        url,
        headers:header?header:{
            "Content-Type":"application/json"
        },
        data:body
       }
       //axios Instance
       
       return axios(config).then((data)=>{
        return data
       }).catch((error)=>{
        return error
       })
}

此api.js来自后端:

require("dotenv").config();
const express=require('express');
const app=express();
const cors=require('cors');

require("./db/conn");
const router=require("./routes/router");
const PORT=4002;

//middleware
app.use(express.json());
app.use(cors());
app.use(router);


app.listen(PORT,()=> console.log("Server connected!!"));

这是来自后端的routes.js:

const express=require("express");
const router=new express.Router();
const controllers=require("../controllers/userControllers");

// Routes
router.post("/user/register",controllers.userregister);
router.post("/user/sendotp",controllers.userOtpSend);


module.exports=router;

这是来自后端的用户控制器文件

const users=require("../models/userSchema")
const userotp=require("../models/userOtp");
const nodemailer=require("nodemailer");

//email config
const transporter=nodemailer.createTransport({
    service:"gmail",
    host: 'smtp.gmail.com',
  port: 465,
  secure: true,
    auth:{
        user:process.env.EMAIL,
        pass:process.env.PASSWORD
    }

})


exports.userregister=async (req,res)=>{
     const {fname,email,password}=req.body;
     if(!fname||!email||!password){
        res.status(400).json({error:"Please Enter All Input Data"});
     }
     try{
        const preuser=await users.findOne({email:email});
        
        if(preuser){
            res.status(400).json({error:"This User name is already exist in Our database"})
        }
        else{
            
            const userregister=new users({
                fname,email,password
            });
            
            //here password hashing
            const storeData=await userregister.save();
            res.status(200).json(storeData);
        }
     }
     catch(error){
       res.status(400).json({error:"Invalid Details"})
     }
}
//user send otp
exports.userOtpSend=async(req,res)=>{
    const {email}=req.body;
    
    if(!email){
        res.status(400).json({error:"Please Enter Your Email"})
    }
    try{
        const preuser=await users.findOne({email:email});
        if(preuser){
             const OTP=Math.floor(100000+Math.random()*900000);
             const existEmail=await userotp.findOne({email:email});
             if(existEmail){
                const updateData=await userotp.findByIdAndUpdate({_id:existEmail._id},{
                    otp:OTP
                },{new:true});
                await updateData.save();
const mailOptions={
    from:process.env.EMAIL,
    to:email,
    subject:"Sending Email For Otp Validation",
    text:`OTP:- ${OTP}`
}
transporter.sendMail(mailOptions,(error,info)=>{
    if(error){
        console.log("error",error);
        res.status(400).json({error:"email not send"});
    }
    else{
        console.log("Email sent",info.response);
        res.status()
    }
})

             }
             else{
                const saveOtpData=new userotp({
                    email,otp:OTP
                });
                await saveOtpData.save();
             }
        }
        else{
            res.status(400).json({error:"This User not exist in our Database"});
        }
    }
    catch(error){
           res.status(400).json({error:"Invalid Details",error})
    }
}
kknvjkwl

kknvjkwl1#

最有可能的问题是发送电子邮件后的响应中缺少状态代码:

// backend ../controllers/userControllers
console.log("Email sent",info.response);
res.status()

......而您期望200代码触发页面导航:

// Front Login
if(response.status===200){
  navigate("/user/otp");
}

话虽如此,只是res.status()本身就很奇怪,你可能是想让res.send()正确地终止处理,Express默认使用200状态码。
此外,Axios默认将2xx范围之外的状态码视为错误(参见validateStatus配置选项),您可以在catch中处理该错误,但静默返回error对象,该对象不直接作为响应(但仍保存在error.response中)。

相关问题