React TextField按键后失焦问题:使用defaultValue致状态不更新
解决TextField按键失焦与状态更新冲突问题
问题根源
你把Login组件定义在了UserAuth组件内部,每次UserAuth因状态更新(比如输入框内容变化触发setEmail/setPassword)重新渲染时,都会重新创建一个全新的Login组件。旧组件被卸载、新组件挂载,直接导致输入框失去焦点。而改用defaultValue时,输入框变成非受控组件,状态无法和组件的state绑定,自然就停更了。
解决方案
把Login组件移到UserAuth外部作为独立组件,通过props传递需要的状态和方法,同时保持输入框为受控组件(用value绑定state)。
修正后的完整代码
import { useState } from 'react'; import { Container, TextField, Button } from '@mui/material'; // 独立定义Login组件 const Login = ({ email, password, handleEmail, handlePassword, handleSubmit, setSwitchForm }) => { return ( <div className="login-div"> <h1>Login</h1> <Container maxWidth="sm"> <p className="login-text">Email</p> <TextField key="email" id="outlined-basic" label="Email" variant="outlined" className="text-field" onChange={handleEmail} value={email} /> <p className="login-text">Password</p> <TextField key="password" id="outlined-basic" label="Password" variant="outlined" className="text-field" onChange={handlePassword} value={password} /> <Button variant="contained" className="login-button" onClick={handleSubmit} > Login </Button> <p> Don't have an account?{" "} <span className="switch-form" onClick={() => setSwitchForm(false)} > Sign up </span> </p> </Container> </div> ); }; const UserAuth = () => { const [switchForm, setSwitchForm] = useState(false) const [password, setPassword] = useState(""); const [email, setEmail] = useState(""); const handleEmail = (e) => { console.log(e.target.value); setEmail(e.target.value); }; const handlePassword = (e) => { setPassword(e.target.value); }; const handleSubmit = () => { console.log("email and pass", email, password); console.log("login"); }; return <Login email={email} password={password} handleEmail={handleEmail} handlePassword={handlePassword} handleSubmit={handleSubmit} setSwitchForm={setSwitchForm} />; };
关键改动说明
- 将
Login组件移到UserAuth外部,避免父组件每次渲染都重新创建子组件,从根源解决失焦问题。 - 通过props传递状态和方法,保证子组件能正常访问父组件的state和回调函数。
- 保留
value绑定状态,维持输入框的受控组件特性,确保状态能随输入正常更新。
内容的提问来源于stack exchange,提问作者SahilN
相关产品推荐
相关产品推荐

