React项目点击按钮打开react-new-window新窗口后立即关闭问题排查
故障原因
- 核心触发点:新窗口内首次加载
SignInPage时会触发Discord授权跳转,页面跳转前会触发onUnload事件,父组件绑定的onUnload={() => setnewWindow(false)}会直接卸载NewWindow组件,而react-new-window的默认逻辑就是组件卸载时自动关闭关联的新窗口,导致窗口刚打开就被销毁。 - 鉴权逻辑错误:
useSession返回的status只有loading、authenticated、unauthenticated三个字符串有效值,用!status作为逻辑执行的判断条件完全不符合状态规则,会导致鉴权逻辑在组件挂载的初始瞬间就误触发,提前发起跳转。 - 渲染条件冲突:父组件给
NewWindow加了!session的渲染判断,父窗口一旦检测到登录态更新,会直接卸载NewWindow组件关窗,和新窗口自身的关窗逻辑冲突。
修复方案
父组件代码调整
- 移除
NewWindow渲染条件里的!session判断,父组件只负责控制窗口打开,关窗逻辑完全交给新窗口页面处理 - 移除
NewWindow上的onUnload事件绑定,避免新窗口内页面跳转时触发父组件的误卸载逻辑
修正后父组件相关代码:
<Button onClick={() => setnewWindow(true)}>Login</Button> { newWindow ? ( <NewWindow url='../components/signIn' />) : null }
SignInPage 代码调整
- 去掉
useSession解构时给status加的多余默认值,直接使用hook返回的原生状态 - 修正鉴权判断逻辑:等
status脱离loading状态(鉴权结果稳定)后再执行对应操作:未登录就发起Discord授权,已登录就关闭当前窗口
修正后SignInPage代码:
import { useEffect } from "react"; import { signIn, useSession } from "next-auth/react"; const SignInPage = () => { const { data: session, status } = useSession(); useEffect(() => { // 鉴权状态还在加载,不执行任何逻辑 if (status === "loading") return; if (status === "unauthenticated") { // 未登录,跳转Discord授权页 void signIn('discord'); } if (status === "authenticated") { // 登录完成,关闭当前窗口 window.close(); } }, [session, status]) return <div>登录授权跳转中,请稍候...</div>; } export default SignInPage;
内容的提问来源于stack exchange,提问作者Aditya Kirad
相关产品推荐
相关产品推荐

