ReactJS функция onClick вызывается дважды - PullRequest
0 голосов
/ 25 апреля 2020

Когда пользователь нажимает кнопку login , пользователь должен получить соответствующее окно с предупреждением, если вход в систему успешен или неуспешен. При нажатии на кнопку запускается функция useDetails (). Во внешнем интерфейсе пользователь может либо ввести электронную почту, либо мобильный телефон, и пароль является обязательным, но onClick запускает функцию 2 раза, и в результате 2 раза появляется окно предупреждения ie, остальная часть выполняется каждый раз

import React, { useState } from 'react'
import { Form, FormGroup, Label, Input, Button, Card, CardTitle, Row, Col } from 'reactstrap'
import firebase from "../firebase";


function Login() {
    const [email, setEmail] = useState('');
    const [mobile, setMobile] = useState('');
    const [password, setPassword] = useState('');
    var CryptoJS = require("crypto-js");

    function useDetails() {
        firebase
            .firestore()
            .collection("users")
            .get().then((snapshot) => {
                snapshot.docs.forEach((doc) => {
                    // console.log(doc.data().Mobile);
                    var bytes = CryptoJS.AES.decrypt(doc.data().Password, 'secret key 123');
                    var plaintext = bytes.toString(CryptoJS.enc.Utf8);
                    var fname = doc.data().Full_name;
                    if (email === '' && mobile === doc.data().Mobile) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
                        }
                        else { alert("Wrong 1 or more credentials.."); }
                    }
                    else if (mobile === '' && email === doc.data().E_mail) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
                        }
                        else { alert("Wrong 1 or more credentials.."); }
                    }
                    else {
                        alert("For a successful login either enter Mobile no. or enter Email id and password is mandatory");

                    }
                })
            });

        setEmail('');
        setMobile('');
        setPassword('');
    }
    const [passwordType, setPasswordType] = useState('password');
    const [passwordToggleText, setPasswordToggleText] = useState('Show');
    const passwordToggle = () => {
        if (passwordType === "password") {
            setPasswordType('text')
            setPasswordToggleText('Hide')
        }
        else {
            setPasswordType('password')
            setPasswordToggleText('Show')
        }
    }
    return (
        <Form className="form col-12" >
            <Row>
                <Card body >
                    <CardTitle><h4><b>Log In</b></h4></CardTitle>
                    <FormGroup>
                        <Row>
                            <Col><Label className="label ml-3">Mobile</Label></Col>
                        </Row>
                        <Row>
                            <Col xs="3" className="ml-3">
                                <Input type="code" placeholder="+91" readOnly />
                            </Col>
                            <Col xs="8">
                                <Input type="text" placeholder="Mobile" value={mobile} onChange={e => setMobile(e.target.value)} />
                            </Col>
                        </Row>
                        <Col className="separator mt-4 text-muted"> O R </Col>
                        <Col>
                            <Label className="label">Email</Label>
                            <Input type="email" placeholder="Email" value={email} onChange={e => setEmail(e.target.value)} />
                        </Col>
                        <Col className="separator mt-4 text-muted"> A N D </Col>
                        <Col>
                            <Label className="label">Password</Label>
                            <Input type={passwordType} placeholder="Password" value={password} onChange={e => setPassword(e.target.value)} />
                            <span className="togglePassword" onClick={passwordToggle}><b>{passwordToggleText}</b></span>
                        </Col>
                    </FormGroup>

                    <Button color="primary" size="lg" block onClick={useDetails}>Log In</Button>
                </Card>
            </Row>
        </Form>
    )
}

export default Login
* Код 1007 * выше - это полный пример, а код ниже - это часть, с которой я сталкиваюсь в
import React, { useState } from 'react'
import { Form, FormGroup, Label, Input, Button, Card, CardTitle, Row, Col }from 'reactstrap'
import firebase from "../firebase";


function Login() {
    const [email, setEmail] = useState('');
    const [mobile, setMobile] = useState('');
    const [password, setPassword] = useState('');
    var CryptoJS = require("crypto-js");

    function useDetails() {
        firebase
            .firestore()
            .collection("users")
            .get().then((snapshot) => {
                snapshot.docs.forEach((doc) => {
                    // console.log(doc.data().Mobile);
                    var bytes = CryptoJS.AES.decrypt(doc.data().Password, 'secret key 123');
                    var plaintext = bytes.toString(CryptoJS.enc.Utf8);
                    var fname = doc.data().Full_name;
                    if (email === '' && mobile === doc.data().Mobile) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
                        }
                        else { alert("Wrong 1 or more credentials.."); }
                    }
                    else if (mobile === '' && email === doc.data().E_mail) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
                        }
                        else { alert("Wrong 1 or more credentials.."); }
                    }
                    else {
                        alert("For a successful login either enter Mobile no. or enter Email id and password is mandatory");

                    }
                })
            });

        setEmail('');
        setMobile('');
        setPassword('');
    }

    return (
        <Form className="form col-12" >
            <Row>
                <Card body >
                    <CardTitle><h4><b>Log In</b></h4></CardTitle>
                    <Button color="primary" size="lg" block onClick={useDetails}>Log In</Button>
                </Card>
            </Row>
        </Form>
    )
}

export default Login

При каждом нажатии кнопки остальная часть выполняется даже если другая if и else-if части исполняются Это ссылка для веб-сайта. , затем нажмите кнопку входа в систему

Email: rijusaha1234@gmail.com Пароль: Mypassword1 #

Ответы [ 4 ]

1 голос
/ 25 апреля 2020

Ваш forEach l oop возвращает две записи с сервера Firebase, поэтому ваш код выполняется дважды, поэтому, пожалуйста, проверьте результат на FireBase. 'snapshot.docs.forEach ((do c) => {})' проверьте это.

В любом случае, я просто изменяю forEach l oop на l oop, чтобы избежать дальнейшего выполнения, если вы получить условие true или false.

import React, { useState } from 'react'
import { Form, FormGroup, Label, Input, Button, Card, CardTitle, Row, Col }from 'reactstrap'
import firebase from "../firebase";


function Login() {
    const [email, setEmail] = useState('');
    const [mobile, setMobile] = useState('');
    const [password, setPassword] = useState('');
    var CryptoJS = require("crypto-js");

    function useDetails() {
        firebase
            .firestore()
            .collection("users")
            .get().then((snapshot) => {

             for(let x=0; x<snapshot.length; x++){
let doc = snapshot[x];

                    // console.log(doc.data().Mobile);
                    var bytes = CryptoJS.AES.decrypt(doc.data().Password, 'secret key 123');
                    var plaintext = bytes.toString(CryptoJS.enc.Utf8);
                    var fname = doc.data().Full_name;
                    if (email === '' && mobile === doc.data().Mobile) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
break;
                        }
                        else { alert("Wrong 1 or more credentials.."); 
break;
}
                    }
                    else if (mobile === '' && email === doc.data().E_mail) {
                        if (password === plaintext) {
                            alert("Successfully logged in as : " + fname);
break;
                        }
                        else { alert("Wrong 1 or more credentials..");
break;
 }
                    }
                    else {
                        alert("For a successful login either enter Mobile no. or enter Email id and password is mandatory");
break;

                    }
            });

        setEmail('');
        setMobile('');
        setPassword('');
    }

    return (
        <Form className="form col-12" >
            <Row>
                <Card body >
                    <CardTitle><h4><b>Log In</b></h4></CardTitle>
                    <Button color="primary" size="lg" block onClick={useDetails}>Log In</Button>
                </Card>
            </Row>
        </Form>
    )
}

export default Login

1 голос
/ 25 апреля 2020

Вы получаете всех пользователей через firebase.firestore().collection("users").get(). В вашем случае это два пользователя. Так что, по крайней мере, для одной из них выполняется «другая» часть, поэтому вы видите двойное предупреждение.

    function useDetails() {
        firebase
            .firestore()
            .collection("users")
            .get().then((snapshot) => {
                const user = snapshot.docs.find(doc => (email === '' && mobile === doc.data().Mobile) || (mobile === '' && email === doc.data().E_mail));
                if (!user) {
                    // Matching user not found
                    alert("For a successful login either enter Mobile no. or enter Email id and password is mandatory");
                    return;
                }
                var bytes = CryptoJS.AES.decrypt(user.data().Password, 'secret key 123');
                var plaintext = bytes.toString(CryptoJS.enc.Utf8);
                if (password !== plaintext) {
                     alert("Wrong 1 or more credentials..");
                     return;
                }
                var fname = user.data().Full_name;
                alert("Successfully logged in as : " + fname);
            });

        setEmail('');
        setMobile('');
        setPassword('');
    }
1 голос
/ 25 апреля 2020

Попробуйте использовать функцию стрелки вместо обычной на function useDetails() ваша функция будет равна const useDetails =()=>{...}, а ваша кнопка входа будет выглядеть как <Button color="primary" size="lg" block onClick={() => useDetails()}>Log In</Button>

0 голосов
/ 25 апреля 2020

В index.js файле найдите код ниже и удалите теги <React.StrictMode> .. </React.StrictMode>.

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

После удаления тега:

ReactDOM.render(<App />, document.getElementById('root'));
...