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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:10:50