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
相关产品推荐
相关产品推荐

