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

React登录页添加原生JS切换动画后页面无法渲染如何解决

问题根因

你写的原生DOM操作代码执行时机早于React组件挂载:组件还没渲染到页面时,document.getElementById就已经开始查询DOM,拿到的signUpButton、signInButton、container全是null,后续给null绑定事件、操作classList时会直接抛出JS错误,导致整个登录页渲染中断。

推荐修复方案(React标准实现)

React是声明式框架,不需要手动查询DOM、绑定事件、修改类名,直接用组件状态驱动视图更新即可,完全兼容你已经写好的CSS切换动画,不需要改动任何CSS代码。
修复后的完整组件代码如下:

import React, { useState } from 'react';
const Loginpart = () => {
// 控制面板激活状态,默认展示登录面板
const [isRightPanelActive, setIsRightPanelActive] = useState(false);

return (
    <div>
        <section className="position-relative pb-0">
            <div className="gen-login-page-background"></div>
            {/* 根据状态动态绑定切换类名 */}
            <div className={`container ${isRightPanelActive ? 'right-panel-active' : ''}`} id="container">
                <div className="form-container sign-up-container">
                    <form action="#">
                        <h1>Create Account</h1>
                        <span>or use your email for registration</span>
                        <input type="text" placeholder="Name" />
                        <input type="email" placeholder="Email" />
                        <input type="password" placeholder="Password" />
                        <button>Sign Up</button>
                    </form>
                </div>
                <div className="form-container sign-in-container">
                    <form action="#">
                        <h1>Sign in</h1>
                        <span>or use your account</span>
                        <input type="email" placeholder="Email" />
                        <input type="password" placeholder="Password" />
                        <a href="#">Forgot your password?</a>
                        <button>Sign In</button>
                    </form>
                </div>
                <div className="overlay-container">
                    <div className="overlay">
                        <div className="overlay-panel overlay-left">
                            <h1>Welcome Back!</h1>
                            <p>To keep connected with us please login with your personal info</p>
                            {/* 点击直接修改状态切换面板 */}
                            <button className="ghost" id="signIn" onClick={() => setIsRightPanelActive(false)}>Sign In</button>
                        </div>
                        <div className="overlay-panel overlay-right">
                            <h1>Hello, Friend!</h1>
                            <p>Enter your personal details and start journey with us</p>
                            {/* 点击直接修改状态切换面板 */}
                            <button className="ghost" id="signUp" onClick={() => setIsRightPanelActive(true)}>Sign Up</button>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
);
};

export default Loginpart;

替换原来的Loginpart组件即可,之前写的单独的原生DOM操作代码可以直接删掉,不需要保留。

不推荐的兼容写法(硬用原生DOM)

如果你一定要照搬原生JS的DOM操作逻辑,必须把DOM查询、事件绑定逻辑放到useEffect钩子中执行,保证代码运行时组件已经完成挂载,同时要记得清理绑定的事件避免内存泄漏:

import React, { useEffect } from 'react';
const Loginpart = () => {
useEffect(() => {
    const signUpButton = document.getElementById('signUp')
    const signInButton = document.getElementById('signIn');
    const container = document.getElementById('container');

    const handleSignUpClick = () => container.classList.add("right-panel-active");
    const handleSignInClick = () => container.classList.remove("right-panel-active");

    signUpButton.addEventListener('click', handleSignUpClick);
    signInButton.addEventListener('click', handleSignInClick);

    // 组件卸载时移除事件监听
    return () => {
        signUpButton.removeEventListener('click', handleSignUpClick);
        signInButton.removeEventListener('click', handleSignInClick);
    }
}, [])

// 这里的JSX和你最初写的完全一致即可
return (
    <div>
        <section className="position-relative pb-0">
            <div className="gen-login-page-background"  ></div>
            <div className="container" id="container">
                <div className="form-container sign-up-container">
                    <form action="#">
                        <h1 >Create Account</h1>
                        <span>or use your email for registration</span>
                        <input type="text" placeholder="Name" />
                        <input type="email" placeholder="Email" />
                        <input type="password" placeholder="Password" />
                        <button>Sign Up</button>
                    </form>
                </div>
                <div className="form-container sign-in-container">
                    <form action="#">
                        <h1  >Sign in</h1>
                        <span>or use your account</span>
                        <input type="email" placeholder="Email" />
                        <input type="password" placeholder="Password" />
                        <a href="#">Forgot your password?</a>
                        <button>Sign In</button>
                    </form>
                </div>
                <div className="overlay-container">
                    <div className="overlay">
                        <div className="overlay-panel overlay-left">
                            <h1>Welcome Back!</h1>
                            <p>To keep connected with us please login with your personal info</p>
                            <button className="ghost" id="signIn">Sign In</button>
                        </div>
                        <div className="overlay-panel overlay-right">
                            <h1>Hello, Friend!</h1>
                            <p>Enter your personal details and start journey with us</p>
                            <button className="ghost" id="signUp">Sign Up</button>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
);
};

export default Loginpart;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:57:25