اذهب إلى المحتوى
  • 0

submit الأولى لا تعمل وعند الضغط على الزر مرة أخرى تعمل بشكل طبيعي مالحل؟؟

محمد الحربي36

السؤال

أقوم بعمل مشروع بـ MERN وأعمل الان على عملية مصادقة المستخدم عندما أضغط على زر "تسجيل دخول" المفترض أن يقوم الكونسول في المتصفح بطباعة رمز التوكن وينقلني للصفحة الرئيسية 

ولكن بدلا من ذلك يقوم بنقلي للصفحة الرئيسية بشكل طبيعي ولكن الكونسول لا يقوم بطباعة التوكن فقمت بتعطيل الكود الذي ينقلني للصفحة الرئيسية ثم بعد التجربة اكتشفت أن في الضغطة الأولى على الزر يقوم الكونسول بطباعة الداتا بشكل طبيعي و status 200 ويطبع توكن فارغ والضغطة الثانية يقوم بطباعة التوكن بشكل طبيعي ولم أعرف مالخطأ في الأكواد فأرجو المساعدة في ذلك

 

ملف authAction.js

import {postDataApi} from "../../utils/fetchDataApi";
import {ALERT_TYPES} from "./alertActins";

export const TYPES = {
    AUTH : 'AUTH'
}

export const login = (data) => async (dispatch) => {
    try {
        const res = await postDataApi(`login`, data)
        console.log(res);
        localStorage.setItem('login', true);
        dispatch({
            type: 'AUTH' ,
            payload: {
                token: res.data.access_token,
                user: res.data.user
            }
        })
        // dispatch({
        //     type: ALERT_TYPES.ALERT,
        //     payload: {
        //         loading: true,
        //     }
        // })

        // console.log(data)

        localStorage.setItem('login', true);

        // dispatch({
        //     type: ALERT_TYPES.ALERT,
        //     payload: {
        //         success: res.data.msg
        //     }
        // })

    } catch (error) {
        console.log(error);
        // dispatch({
        //     type: ALERT_TYPES.ALERT,
        //     payload: {
        //         error: error.response.data.msg,
        //     }
        // })
    }
}
export const refreshToken = () => async (dispatch) => {
    const login = localStorage.getItem('login')
    // console.log(login);
    if(login) {
    // dispatch({
    //     type: 'ALERT',
    //     payload: {
    //         loading: true
    //     }
    // })
    try {
        const res = await postDataApi('refresh_token');
        dispatch({
            type: 'AUTH' ,
            payload: {
                token: res.data.access_token,
                user: res.data.user
            }
        })
        
        // dispatch({
        //     type: ALERT_TYPES.ALERT,
        //     payload: {
        //         success: res.data.msg
        //     }
        // })

    } catch (error) {
        console.log(error);
        // dispatch({
        //     type:'ALERT',
        //     payload: {
        //         error: error.response.data.msg
        //     }
        // })
    }
}}

ملف login.jsx

import { useState } from "react";
import { Link } from "react-router-dom";
import "./login.scss";
import axios from "axios";
import VisibilityIcon from '@mui/icons-material/Visibility';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import {login} from "../../redux/actions/authActions.js";
import {useDispatch, useSelector} from "react-redux";
import Alert from "../../components/Alert";

export default function Login() {
  const initialState = {email:'', password: ''}
  const [showpass, setShowpass] = useState(false);
  const [userData, setUserData] = useState(initialState);
  const [isCorrect, setIsCorrect] = useState(true);

  const auth = useSelector(state => state);
  const dispatch = useDispatch();
  const {email, password} = userData;


  const handleChange = (e) => {
    const {name, value} = e.target;
    setUserData({...userData, [name]:value })
  }
  
  const handlevaid = async () => {
    if (!auth.token) setIsCorrect(false);
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    setUserData({email, password })
  dispatch(login(userData))
  await handlevaid()
  console.log(auth)
  }
  
  // const handleLogin = async (e) => {
  //   e.preventDefault();
    // try {
    //   const config = {
    //     headers: {
    //       "Content-type":"application/json"
    //     }
    //   }

    //   const { data } = await axios.post(
    //     '/api/users/login',
    //     {
    //       email,
    //       password,
    //     },
    //     config
    //   );
      
    //   console.log(data);
    //   localStorage.setItem("userInfo", JSON.stringify(data));
    // } catch (error) {
    //   console.log(error);//.response.data.message
    // }

  // };


  return (
    <div className="Login">
      <div className="card">
        <div className="left">
          <h1>Hello world</h1>
          <p>
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Obcaecati
            aspernatur illum porro dolorum numquam corporis adipisci quos magni
            voluptatum nostrum soluta excepturi, vel quas libero exercitationem
            dignissimos! Nostrum, earum ex?
          </p>
          <span>Don't you ave an account?</span>
          <Link to="/register">
          <button>Register</button>
          </Link>
        </div>
        <div className="right">
          {/* {error && <ErrorMessage>{error}</ErrorMessage>} */}
          {/* {loading && <Loading />} */}
          <h1>Login</h1>
          <form onSubmit={handleLogin}>
            <div>
            <span style={{display: isCorrect ? "none" : "inline", color:"red"}}>Email or Password is incorrect!</span>
            </div>
            <input onChange={handleChange} name='email' value={email} type="email" placeholder="Enter Email" />
            <div>
            <input onChange={handleChange} name='password' value={password} type= {showpass ? "text" : "password"} placeholder="Password" />
            {!showpass 
            ? <VisibilityIcon onClick={()=>setShowpass(!showpass)} className="showpass"/> 
            : <VisibilityOffIcon onClick={()=>setShowpass(!showpass)} className="showpass"/>}
            </div>
            <button type="submit">Login</button>
          </form>
        </div>
      </div>
    </div>
  )
}

ملف fetchDataApi.js

import axios from "./axios";

export const getDataApi = async (url, token) => {
    const res = await axios.get(`/api/${url}`, {
        headers: {Authorization: token}
    })
    return res;
}

export const postDataApi = async (url, post, token) => {
    const res = await axios.post(`/api/${url}`, post, {
        headers: {Authorization: token}
        /*
        headers: {
            Accept: "application/json",
            Authorization: `Bearer${token}`
        }
         */
    })
    // console.log(res.data.access_token);
    return res;
}

export const putDataApi = async (url, post, token) => {
    const res = await axios.put(`url/${url}`, post, {
        headers: {Authorization: token}
    })
    return res;
}

export const patchDataApi = async (url, post, token) => {
    const res = await axios.patch(`url/${url}`, post, {
        headers: {Authorization: token}
    })
    return res;
}

export const deleteDataApi = async (url, token) => {
    const res = await axios.delete(`url/${url}`, {
        headers: {Authorization: token}
    })
    return res;
}

صورة الكونسول

token error.png

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0
بتاريخ 9 ساعة قال عمر قره محمد:

هل يمكنك مشاركة ملفات المشروع بالكامل مع الـ backend حتى استطيع اختبار الكود.

هل عرفت ماهو الخطأ أخي

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 8 ساعة قال Mustafa Suleiman:

هل قمت بتجربة عمل طباعة عند حدوث تغير في الـ Token، مثال:

useEffect(() => {
  console.log(auth);
}, [auth.token]);

 

لا

هل أجرب هذا في ملف login.jsx أو ملف authActions.js ؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 10 ساعة قال Mustafa Suleiman:

هل قمت بتجربة عمل طباعة عند حدوث تغير في الـ Token، مثال:

useEffect(() => {
  console.log(auth);
}, [auth.token]);

 

لأنه عندما أقوم بعملية تسجيل الدخول يقوم الكونسول بطباعة console.log موجودة في login.jsx وأخرى موجودة في ملف authActions.js

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 11 ساعة قال Mustafa Suleiman:

هل قمت بتجربة عمل طباعة عند حدوث تغير في الـ Token، مثال:

useEffect(() => {
  console.log(auth);
}, [auth.token]);

 

أخي المشكلة الآن أن الـ span الأحمر الذي من المفترض أن لا يظهر إلا عند عدم وجود التوكن يعمل بالعكس الآن

عند وجود التوكن يظهر

وعند عدم وجود التوكن لا يظهر

هذا آخر كود وصلت إليه

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import "./login.scss";
import axios from "axios";
import VisibilityIcon from '@mui/icons-material/Visibility';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import {login} from "../../redux/actions/authActions.js";
import {useDispatch, useSelector} from "react-redux";
import Alert from "../../components/Alert";

export default function Login() {
  const initialState = {email:'', password: ''}
  const [showpass, setShowpass] = useState(false);
  const [userData, setUserData] = useState(initialState);
  const [isCorrect, setIsCorrect] = useState(true);
  const [clicked, setClicked] = useState(false);

  const auth = useSelector(state => state);
  const dispatch = useDispatch();
  const {email, password} = userData;

  useEffect(() => {
    if(clicked){
      console.log(auth);
      handlevalid()
    }
}, [auth]);

  const handleChange = (e) => {
    const {name, value} = e.target;
    setUserData({...userData, [name]:value })
  }
  
  const handlevalid = async () => {
    if (!auth.token) {setIsCorrect(false)}
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    setUserData({email, password })
  dispatch(login(userData))
  }
  
  

  return (
    <div className="Login">
      <div className="card">
        <div className="left">
          <h1>Hello world</h1>
          <p>
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Obcaecati
            aspernatur illum porro dolorum numquam corporis adipisci quos magni
            voluptatum nostrum soluta excepturi, vel quas libero exercitationem
            dignissimos! Nostrum, earum ex?
          </p>
          <span>Don't you ave an account?</span>
          <Link to="/register">
          <button>Register</button>
          </Link>
        </div>
        <div className="right">
          <h1>Login</h1>
          <form onSubmit={handleLogin}>
            <div>
            <span style={{display: isCorrect ? "none" : "inline", color:"red"}}>Email or Password is incorrect!</span>
            </div>
            <input onChange={handleChange} name='email' value={email} type="email" placeholder="Enter Email" />
            <div>
            <input onChange={handleChange} name='password' value={password} type= {showpass ? "text" : "password"} placeholder="Password" />
            {!showpass 
            ? <VisibilityIcon onClick={()=>setShowpass(!showpass)} className="showpass"/> 
            : <VisibilityOffIcon onClick={()=>setShowpass(!showpass)} className="showpass"/>}
            </div>
            <button type="submit" onClick={()=>setClicked(true)}>Login</button>
          </form>
        </div>
      </div>
    </div>
  )
}

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ منذ ساعة مضت قال محمد الحربي:

أخي المشكلة الآن أن الـ span الأحمر الذي من المفترض أن لا يظهر إلا عند عدم وجود التوكن يعمل بالعكس الآن

عند وجود التوكن يظهر

وعند عدم وجود التوكن لا يظهر

هذا آخر كود وصلت إليه

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import "./login.scss";
import axios from "axios";
import VisibilityIcon from '@mui/icons-material/Visibility';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import {login} from "../../redux/actions/authActions.js";
import {useDispatch, useSelector} from "react-redux";
import Alert from "../../components/Alert";

export default function Login() {
  const initialState = {email:'', password: ''}
  const [showpass, setShowpass] = useState(false);
  const [userData, setUserData] = useState(initialState);
  const [isCorrect, setIsCorrect] = useState(true);
  const [clicked, setClicked] = useState(false);

  const auth = useSelector(state => state);
  const dispatch = useDispatch();
  const {email, password} = userData;

  useEffect(() => {
    if(clicked){
      console.log(auth);
      handlevalid()
    }
}, [auth]);

  const handleChange = (e) => {
    const {name, value} = e.target;
    setUserData({...userData, [name]:value })
  }
  
  const handlevalid = async () => {
    if (!auth.token) {setIsCorrect(false)}
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    setUserData({email, password })
  dispatch(login(userData))
  }
  
  

  return (
    <div className="Login">
      <div className="card">
        <div className="left">
          <h1>Hello world</h1>
          <p>
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Obcaecati
            aspernatur illum porro dolorum numquam corporis adipisci quos magni
            voluptatum nostrum soluta excepturi, vel quas libero exercitationem
            dignissimos! Nostrum, earum ex?
          </p>
          <span>Don't you ave an account?</span>
          <Link to="/register">
          <button>Register</button>
          </Link>
        </div>
        <div className="right">
          <h1>Login</h1>
          <form onSubmit={handleLogin}>
            <div>
            <span style={{display: isCorrect ? "none" : "inline", color:"red"}}>Email or Password is incorrect!</span>
            </div>
            <input onChange={handleChange} name='email' value={email} type="email" placeholder="Enter Email" />
            <div>
            <input onChange={handleChange} name='password' value={password} type= {showpass ? "text" : "password"} placeholder="Password" />
            {!showpass 
            ? <VisibilityIcon onClick={()=>setShowpass(!showpass)} className="showpass"/> 
            : <VisibilityOffIcon onClick={()=>setShowpass(!showpass)} className="showpass"/>}
            </div>
            <button type="submit" onClick={()=>setClicked(true)}>Login</button>
          </form>
        </div>
      </div>
    </div>
  )
}

 

يحتمل أن المشكلة أساسا هي طريقة عمل المكون لديك، 

فعند الضغط على زر تقديم النموذج يقوم بتغيير حالة المتغير clicked، بينما يتم تنفيذ دالة handleLogin والتي تقوم بإرسال البيانات المدخلة إلى المتجر بواسطة خطاف dispatch والتحقق من صحة البيانات وتخزينها باستخدام useState، ولكنها لا تنفذ الدالة handlevalid المسؤولة عن التحقق من صحة الرمز المميز token الذي يرجعه المتجر. لذلك، يجب نقل دالة handlevalid من ال useEffect إلى داخل دالة handleLogin، بعد استدعاء خطاف dispatch، وذلك للتحقق من صحة الرمز المميز الذي يرجعه المتجر في الوقت الحالي.

لتكون على نحو:

const {email, password} = userData;

  const handleChange = (e) => {
    const {name, value} = e.target;
    setUserData({...userData, [name]:value })
  }
  
  const handlevalid = async () => {
    if (!auth.token) {setIsCorrect(false)}
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    handlevalid()
    setUserData({email, password })
    dispatch(login(userData))
  }

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ منذ ساعة مضت قال Adnane Kadri:

يحتمل أن المشكلة أساسا هي طريقة عمل المكون لديك، 

فعند الضغط على زر تقديم النموذج يقوم بتغيير حالة المتغير clicked، بينما يتم تنفيذ دالة handleLogin والتي تقوم بإرسال البيانات المدخلة إلى المتجر بواسطة خطاف dispatch والتحقق من صحة البيانات وتخزينها باستخدام useState، ولكنها لا تنفذ الدالة handlevalid المسؤولة عن التحقق من صحة الرمز المميز token الذي يرجعه المتجر. لذلك، يجب نقل دالة handlevalid من ال useEffect إلى داخل دالة handleLogin، بعد استدعاء خطاف dispatch، وذلك للتحقق من صحة الرمز المميز الذي يرجعه المتجر في الوقت الحالي.

لتكون على نحو:

const {email, password} = userData;

  const handleChange = (e) => {
    const {name, value} = e.target;
    setUserData({...userData, [name]:value })
  }
  
  const handlevalid = async () => {
    if (!auth.token) {setIsCorrect(false)}
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    handlevalid()
    setUserData({email, password })
    dispatch(login(userData))
  }

 

أخي استخدمت هذه الطريقة في البداية ولكنها لم تنجح فقمت بوضع await قبل استدعاء  دالة handlevalid ولم تنجح أيضا 

لقد لاحظت أن span يظهر في الصفحة قبل أن تقوم الـ console.log التي في ملف authActions في السطر 11 بطباعة الـ data 

وهذا على الأغلب بسبب تأخر جلب البيانات من قاعدة البيانات وبالتالي تقوم الدالة handlevalid بإظهار  الـ span

بسبب عدم وجود الرمز المميز token لأن التوكن يظهر بعد جلب البينات 

أخي ملف المشروع قمت بإرفاقه في الأعلى أتمنى منك الإطلاع عليه رجاءا

:- هل هناك طريقة أجعل الـ span يتأخر قليلا أو ينتظر جلب البينات مثلا ؟

تم التعديل في بواسطة محمد الحربي
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...