React:如何在useEffect完成角色设置前阻止页面渲染?
解决权限初始化前页面提前渲染的问题
你的问题核心是useEffect会在组件首次渲染后执行,导致页面先以默认的candidate权限渲染,之后才更新为正确权限。这里给你两种直接可行的解决方案:
方案一:同步初始化权限(推荐,适合当前场景)
因为nookies.get()是同步操作,不需要异步等待,直接在useState的初始化回调里计算正确权限,组件第一次渲染就会用最终权限,完全避免默认值的渲染。
修改后的代码:
function MyApp({ Component, pageProps }: AppProps): JSX.Element { // 同步计算初始权限,无需依赖useEffect const [role] = useState(() => { const auth = nookies.get()["auth"]; if (auth) { const parsedUser = JSON.parse(auth) as unknown as CookieInfo; const { role_id } = parsedUser; if (role_id) { const current_user_role = roles.find(x => x.id === role_id)?.name || 'Candidate'; return current_user_role.replace(' ', '').toLowerCase(); } } // 无权限信息时用默认值 return 'candidate'; }); const auth = nookies.get()["auth"]; let userId = 0; if (auth) { const parsedUser = JSON.parse(auth); userId = parsedUser?.id; } return ( <ThemeProvider theme={customTheme}> <Component {...pageProps} role={role} userId={userId} /> </ThemeProvider> ); }
注意:原来的代码里useEffect依赖了role,会导致权限更新后重复触发useEffect,甚至可能无限循环,这个方案直接去掉了useEffect,从根源解决了问题。
方案二:添加加载状态(适合异步获取权限的场景)
如果之后权限需要异步获取(比如从接口拉取),可以通过加载状态阻止页面渲染,直到权限确定:
function MyApp({ Component, pageProps }: AppProps): JSX.Element { const [role, setRole] = useState<string | null>(null); // null表示未加载完成 const auth = nookies.get()["auth"]; useEffect(() => { const fetchRole = () => { if (auth) { const parsedUser = JSON.parse(auth) as unknown as CookieInfo; const { role_id } = parsedUser; if (role_id) { const current_user_role = roles.find(x => x.id === role_id)?.name || 'Candidate'; const aclRole = current_user_role.replace(' ', '').toLowerCase(); setRole(aclRole); return; } } // 无权限信息时设置默认值 setRole('candidate'); }; fetchRole(); }, [auth]); // 只依赖auth,避免无限循环 // 权限未加载完成时,只显示加载组件 if (role === null) { return <div>加载中...</div>; // 替换成你的自定义加载UI } let userId = 0; if (auth) { const parsedUser = JSON.parse(auth); userId = parsedUser?.id; } return ( <ThemeProvider theme={customTheme}> <Component {...pageProps} role={role} userId={userId} /> </ThemeProvider> ); }
这个方案通过role === null判断加载状态,在权限确定前不渲染业务页面,只显示加载提示,避免用户看到错误的权限内容。
内容的提问来源于stack exchange,提问作者Saltern
相关产品推荐
相关产品推荐

