You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何避免单按钮点击触发两个按钮的点击函数?

登录/注册切换按钮触发多个事件的解决方案

问题描述

实现登录/注册切换功能时,设置了两个按钮,但点击任意一个按钮都会执行切换模式的函数,一次点击触发了两个onClick事件,需要让每个按钮仅执行对应函数。

原始代码

import React, { useState } from "react";
import LockIcon from "@mui/icons-material/Lock";
import VisibilityIcon from "@mui/icons-material/Visibility";
import { GoogleLogin } from "@react-oauth/google";
import jwt_decode from "jwt-decode";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import "./authStyles.css";
import { signUp, signIn } from "../../action/auth/authAction";

const initialStateForm = {
    fName: "",
    lName: "",
    email: "",
    password: "",
    confirmPassword: "",
};

const Auth = () => {
    const [showPassword, setShowPassword] = useState(true);
    const [isSignup, setIsSignup] = useState(false);
    const [formData, setFormData] = useState(initialStateForm);
    const dispatch = useDispatch();
    const navigate = useNavigate();
    const switchMode = () => {
        setIsSignup((prevIsSignup) => !prevIsSignup);
        setShowPassword(false);
        console.log("switchMode " + isSignup);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        console.log("handleSubmit " + isSignup);
        // if (isSignup) {
        //  dispatch(signUp(formData));
        // } else {
        //  dispatch(signIn(formData));
        // }
    };

    const handleChnage = (e) => {
        e.preventDefault();
        setFormData({ ...formData, [e.target.name]: e.target.value });
    };

    const handleShowPassword = () => {
        setShowPassword((prevShowPassword) => !prevShowPassword);
    };

    const googleSuccess = async (res) => {
        const decodeUser = jwt_decode(res.credential);
        dispatch({ type: "AUTH", payload: decodeUser });
        navigate("/");
    };
    const googleFailure = (error) => {
        console.log(error);
        console.log("Google sign in is unsuccessfull");
    };

    return (
        <div>
            <div className="sign-form-container">
                <LockIcon></LockIcon>
                <span>{isSignup ? `Sign Up` : `Sign In`}</span>
                {isSignup && (
                    <>
                        <input
                            type="text"
                            id="fName"
                            name="fName"
                            placeholder="First Name"
                            onChange={handleChnage}
                        />
                        <input
                            type="text"
                            id="lName"
                            name="lName"
                            placeholder="Last Name"
                            onChange={handleChnage}
                        />
                    </>
                )}
                <input
                    type="email"
                    id="email"
                    name="email"
                    placeholder="Email"
                    onChange={handleChnage}
                />
                <input
                    type={showPassword ? `password` : `text`}
                    id="password"
                    name="password"
                    placeholder="Password"
                    onChange={handleChnage}
                />
                <VisibilityIcon onClick={handleShowPassword} />
                {isSignup && (
                    <>
                        <input
                            type="password"
                            id="confirmPassword"
                            name="confirmPassword"
                            placeholder="Confirm password"
                            onChange={handleChnage}
                        />
                    </>
                )}
                <GoogleLogin
                    onSuccess={googleSuccess}
                    onFailure={googleFailure}
                    cookiePolicy="single_host_origin"
                ></GoogleLogin>
                <button type="button" onClick={handleSubmit}> //button 1
                    {isSignup ? `Sign Up` : `Sign In`}
                </button>
                <button type="button" onClick={switchMode}> // button 2
                    {isSignup
                        ? "Already have an account ? Sign In"
                        : "Don't have and account? Sign Up"}
                </button>
            </div>
        </div>
    );
};

export default Auth;

问题原因与修复方案

1. 核心问题:JSX标签内的注释格式错误

你在按钮标签内部使用了//button 1这类单行注释,JSX不支持这种写法,注释会被当作按钮的文本节点渲染,干扰了事件绑定的正常逻辑,导致点击时触发异常事件。

2. 其他需要修正的问题

  • 函数名拼写错误:handleChnage改为handleChange,避免后续调用出错。
  • 冗余代码:handleChange里的e.preventDefault()是多余的,onChange事件不需要阻止默认行为。
  • 状态更新优化:更新formData时使用函数式更新,确保获取最新状态值,避免闭包问题。

修复后的代码

import React, { useState } from "react";
import LockIcon from "@mui/icons-material/Lock";
import VisibilityIcon from "@mui/icons-material/Visibility";
import { GoogleLogin } from "@react-oauth/google";
import jwt_decode from "jwt-decode";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import "./authStyles.css";
import { signUp, signIn } from "../../action/auth/authAction";

const initialStateForm = {
    fName: "",
    lName: "",
    email: "",
    password: "",
    confirmPassword: "",
};

const Auth = () => {
    const [showPassword, setShowPassword] = useState(true);
    const [isSignup, setIsSignup] = useState(false);
    const [formData, setFormData] = useState(initialStateForm);
    const dispatch = useDispatch();
    const navigate = useNavigate();
    const switchMode = () => {
        setIsSignup((prevIsSignup) => !prevIsSignup);
        setShowPassword(false);
        console.log("switchMode " + isSignup);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        console.log("handleSubmit " + isSignup);
        // if (isSignup) {
        //  dispatch(signUp(formData));
        // } else {
        //  dispatch(signIn(formData));
        // }
    };

    const handleChange = (e) => {
        setFormData(prev => ({ ...prev, [e.target.name]: e.target.value }));
    };

    const handleShowPassword = () => {
        setShowPassword((prevShowPassword) => !prevShowPassword);
    };

    const googleSuccess = async (res) => {
        const decodeUser = jwt_decode(res.credential);
        dispatch({ type: "AUTH", payload: decodeUser });
        navigate("/");
    };
    const googleFailure = (error) => {
        console.log(error);
        console.log("Google sign in is unsuccessfull");
    };

    return (
        <div>
            <div className="sign-form-container">
                <LockIcon></LockIcon>
                <span>{isSignup ? `Sign Up` : `Sign In`}</span>
                {isSignup && (
                    <>
                        <input
                            type="text"
                            id="fName"
                            name="fName"
                            placeholder="First Name"
                            onChange={handleChange}
                        />
                        <input
                            type="text"
                            id="lName"
                            name="lName"
                            placeholder="Last Name"
                            onChange={handleChange}
                        />
                    </>
                )}
                <input
                    type="email"
                    id="email"
                    name="email"
                    placeholder="Email"
                    onChange={handleChange}
                />
                <input
                    type={showPassword ? `password` : `text`}
                    id="password"
                    name="password"
                    placeholder="Password"
                    onChange={handleChange}
                />
                <VisibilityIcon onClick={handleShowPassword} />
                {isSignup && (
                    <>
                        <input
                            type="password"
                            id="confirmPassword"
                            name="confirmPassword"
                            placeholder="Confirm password"
                            onChange={handleChange}
                        />
                    </>
                )}
                <GoogleLogin
                    onSuccess={googleSuccess}
                    onFailure={googleFailure}
                    cookiePolicy="single_host_origin"
                ></GoogleLogin>
                {/* button 1 */}
                <button type="button" onClick={handleSubmit}>
                    {isSignup ? `Sign Up` : `Sign In`}
                </button>
                {/* button 2 */}
                <button type="button" onClick={switchMode}>
                    {isSignup
                        ? "Already have an account ? Sign In"
                        : "Don't have an account? Sign Up"}
                </button>
            </div>
        </div>
    );
};

export default Auth;

关键修复点说明

  • 把按钮内的//button 1注释移到标签外,改用JSX支持的{/* 注释内容 */}格式。
  • 修正handleChnage为handleChange,确保函数名正确。
  • 移除handleChange中的e.preventDefault(),因为onChange事件不需要阻止默认行为。
  • 更新setFormData为函数式写法,避免因闭包导致的状态更新不及时问题。

内容的提问来源于stack exchange,提问作者Lakshan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:48:24