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

React内部函数组件表单input输入框无法输入问题修复方案

问题根本原因

问题出在你将RegisterFormInputs、RegisterVerificationForm两个函数组件定义在了父组件RegisterForm的函数作用域内部:

  1. 每次父组件因为状态更新触发重渲染时,都会重新生成这两个子组件函数的全新引用,和上一次渲染时的组件引用完全不一致。
  2. React对比虚拟DOM时,只要发现组件类型的引用变了,就会判定这是完全不同的新组件,直接卸载上一次渲染的旧组件实例、挂载全新的组件实例,不会做状态复用。
  3. 你在输入框输入内容时,onChange触发父组件状态更新→父组件重渲染→生成全新的RegisterFormInputs组件→旧输入框被卸载、新输入框挂载,输入焦点和已输入内容全部丢失,最终表现为输入框完全无法输入内容。
修复方法

优先选择第一种方案,稳定性和可维护性最好:

  • 把两个子组件移到RegisterForm外部定义为独立组件,子组件需要用到的状态、回调函数通过props传入即可。这样组件引用在所有渲染周期中都是稳定的,React可以正常复用组件实例,输入行为就会恢复正常。

如果你不想把组件抽离到外部,也可以选择第二种方案:

  • 不要把这两段UI包装成组件用<Component />的形式渲染,直接把JSX内联写在返回的模板中;如果要复用JSX逻辑,可以提取成普通函数,渲染时直接执行函数拿到JSX返回值即可,不要把它当组件调用。
修复后核心代码示例
// 把子组件移到父组件外部定义,通过props接收需要的参数
const RegisterFormInputs = ({ handleRegisterOnChange, register }) => {
    return <div>
        <h2 className="loginElement">Create profile</h2>
        <label className="loginElement">
            <span className="loginElement">Email</span>
            <input type="email" name="email" className="loginElement" onChange={handleRegisterOnChange} />
        </label>
        <label className="loginElement">
            <span className="loginElement">Password</span>
            <input type="password" name="password" className="loginElement" onChange={handleRegisterOnChange} />
        </label>
        <button type="button" className="submit" onClick={register}>Register</button>
    </div>
}

const RegisterVerificationForm = ({ handleTokenOnChange, confirmRegistration }) => {
    return <div className="verify-registration">
        <h2 className="loginElement text-center">Activate your profile</h2>
        <div className="d-flex justify-content-center align-items-center">
            <TextField id="outlined-basic" label="Verification token" variant="outlined" onChange={handleTokenOnChange} />
            <Timer initialMinutes={10}/>
        </div>
        <div className="mt-3 text-center">
            <Button variant="contained" onClick={confirmRegistration}>Submit</Button>
        </div>
    </div>;
}

function RegisterForm() {
    const [registerInputValues, setRegisterInputValues] = useState({
        email: '', password: ''
    });
    // 原代码缺失验证码相关状态和回调,这里补充基础实现
    const [confirmationToken, setConfirmationToken] = useState('');
    const handleTokenOnChange = (e) => setConfirmationToken(e.target.value);

    const [showRegisterForm, setShowRegisterForm] = useState(true);
    const [showRegisterVerificationForm, setShowRegisterVerificationForm] = useState(false);

    const handleRegisterOnChange = event => {
        const { name, value } = event.target;
        setRegisterInputValues({ ...registerInputValues, [name]: value });
    };

    const register = () => {
        studentsService.registerStudent(registerInputValues)
            .then(response => {
                console.log(response);
            })
            .catch(e => {
                console.log(e);
            });
        setShowRegisterForm(false);
        setShowRegisterVerificationForm(true);
    }

    const confirmRegistration = () => {
        studentsService.confirmRegistration(confirmationToken)
        .then(response => {console.log(confirmationToken, response)
        })
        .catch(e => {console.log(e); alert(e.response.data);});
    }

    return (
        <>
            <div className="cont mt-5">
                <div className="sub-cont">
                    <div className="form sign-up">
                        {showRegisterForm ? <RegisterFormInputs handleRegisterOnChange={handleRegisterOnChange} register={register} /> : null}
                        {showRegisterVerificationForm ? <RegisterVerificationForm handleTokenOnChange={handleTokenOnChange} confirmRegistration={confirmRegistration} /> : null}
                    </div>
                </div>
            </div>
        </>
    )
}

export default RegisterForm;

注:原代码中缺失验证码输入框对应的confirmationToken状态和handleTokenOnChange回调定义,上述示例中已经补充了基础实现,可根据业务需求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 03:09:29