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

表单提交时useEffect首次未触发问题排查与修复求助

问题:useEffect首次提交校验失败,二次点击才生效

代码实现

const Login=(props)=>  {
    const [password,setPassword]=useState(null);
    const [readytosubmit,setReadytosubmit]=useState(false)

    const nameRef=useRef("dim");
    var name=nameRef.current.value;
    const passwordRef=useRef("");
    console.log(name)
    

    useEffect(()=>{
        const getArticles = async () => {
            
            const res = await Axios.get("http://localhost:8080/api/password/"+name);
            setPassword(res.data);
            console.log(password);
          };
          getArticles()},[readytosubmit])  
    
        
    
    function handlesubmit(e){
        //must need
        e.preventDefault();
        setReadytosubmit(true);
        console.log(nameRef.current.value)
        console.log(password) 
        console.log(passwordRef.current.value)
        if(passwordRef.current.value.toString()===password.toString()){
            console.log("Ture Password")
        props.login();}else{
            console.log("false password")
        }
    }
    
    
    return (
        <>
            <div className='Registerform'>
                <h3>Login Form</h3><br></br>
                <Form onSubmit={handlesubmit} >
                    <Form.Group className="mb-3" controlId="formBasicName">
                        <Form.Label>Username</Form.Label>
                        <Form.Control ref={nameRef} type="username" placeholder="Enter your username" />

                    </Form.Group><br></br>
                    

                    <Form.Group className="mb-3" controlId="formBasicPassword">
                        <Form.Label>Password</Form.Label>
                        <Form.Control ref={passwordRef} type="password" placeholder="Password" />
                        
                    </Form.Group><br></br>

                    

                    <Button variant="primary" type="submit">
                        Submit
                    </Button>
                </Form>
            </div>
            
            <Button onClick={props.login} variant="primary">Primary</Button> 
        </>
    )
}

export default Login ;

控制台日志

login.jsx:41 alex <-- i click the submitform
login.jsx:42      <--empty result which is expected the password get from the database
login.jsx:43 123456
login.jsx:47 false password
login.jsx:22 alex
login.jsx:22 alex
login.jsx:30      
login.jsx:22 alex
login.jsx:22 alex
login.jsx:41 alex
login.jsx:42 123456
login.jsx:43 123456 <----have the resubmit after double click
login.jsx:45 Ture Password
index.js:32 loginstatusfalse
index.js:33 login
layout.jsx:28 layout: true
layout.jsx:28 layout: true
login.jsx:22 alex
login.jsx:22 alex

问题原因

  1. 用户名未实时获取:var name=nameRef.current.value定义在组件顶层,仅在组件初始化或重新渲染时执行。用户输入用户名后,组件不会因ref变化触发更新,导致第一次提交时useEffect使用的是初始旧值,请求结果不符合预期。
  2. 异步状态更新时机错误:第一次点击submit时,setReadytosubmit(true)触发组件重渲染,但handlesubmit会立刻校验password——此时useEffect的异步请求尚未完成,password仍是初始的null,因此校验失败。
  3. 依赖项设计冗余:依赖readytosubmit触发请求的逻辑不合理,第一次点击后该状态变为true,后续点击不会再触发状态变更,自然不会触发useEffect。第二次校验成功只是因为第一次useEffect已完成请求并更新了password,并非第二次触发了useEffect。

修复方案

方案一:直接在提交时发起请求(推荐,逻辑更简洁)

去掉readytosubmit状态和useEffect,直接在handlesubmit中完成请求、校验和登录流程:

const Login=(props)=>  {
    const nameRef=useRef("dim");
    const passwordRef=useRef("");

    async function handlesubmit(e){
        e.preventDefault();
        const username = nameRef.current.value;
        const inputPassword = passwordRef.current.value;
        
        try {
            const res = await Axios.get(`http://localhost:8080/api/password/${username}`);
            const dbPassword = res.data;
            if(inputPassword.toString() === dbPassword.toString()){
                console.log("True Password");
                props.login();
            }else{
                console.log("false password");
            }
        } catch (error) {
            console.error("获取密码失败:", error);
        }
    }
    
    return (
        <>
            <div className='Registerform'>
                <h3>Login Form</h3><br></br>
                <Form onSubmit={handlesubmit} >
                    <Form.Group className="mb-3" controlId="formBasicName">
                        <Form.Label>Username</Form.Label>
                        <Form.Control ref={nameRef} type="username" placeholder="Enter your username" />
                    </Form.Group><br></br>

                    <Form.Group className="mb-3" controlId="formBasicPassword">
                        <Form.Label>Password</Form.Label>
                        <Form.Control ref={passwordRef} type="password" placeholder="Password" />
                    </Form.Group><br></br>

                    <Button variant="primary" type="submit">
                        Submit
                    </Button>
                </Form>
            </div>
            
            <Button onClick={props.login} variant="primary">Primary</Button> 
        </>
    )
}

export default Login ;

方案二:调整useEffect依赖与状态逻辑(保留原模式优化)

用state跟踪用户名变化,确保useEffect能实时获取最新输入,并在password更新后再执行校验:

const Login=(props)=>  {
    const [password,setPassword]=useState(null);
    const [username, setUsername] = useState("");
    const passwordRef=useRef("");

    const handleNameChange = (e) => {
        setUsername(e.target.value);
    };

    useEffect(()=>{
        if(!username) return;
        const getArticles = async () => {
            const res = await Axios.get(`http://localhost:8080/api/password/${username}`);
            setPassword(res.data);
        };
        getArticles();
    },[username])
    
    function handlesubmit(e){
        e.preventDefault();
        const inputPassword = passwordRef.current.value;
        if(password && inputPassword.toString() === password.toString()){
            console.log("True Password");
            props.login();
        }else{
            console.log("false password");
        }
    }
    
    return (
        <>
            <div className='Registerform'>
                <h3>Login Form</h3><br></br>
                <Form onSubmit={handlesubmit} >
                    <Form.Group className="mb-3" controlId="formBasicName">
                        <Form.Label>Username</Form.Label>
                        <Form.Control 
                            value={username}
                            onChange={handleNameChange}
                            type="username" 
                            placeholder="Enter your username" 
                        />
                    </Form.Group><br></br>

                    <Form.Group className="mb-3" controlId="formBasicPassword">
                        <Form.Label>Password</Form.Label>
                        <Form.Control ref={passwordRef} type="password" placeholder="Password" />
                    </Form.Group><br></br>

                    <Button variant="primary" type="submit">
                        Submit
                    </Button>
                </Form>
            </div>
            
            <Button onClick={props.login} variant="primary">Primary</Button> 
        </>
    )
}

export default Login ;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:10:29