fix(auth): 登录页不停刷新、无法输入
未登录时五个 Tab 视图会同时挂载各自的 Screen,每个都判定「没登录」,
于是每个都对**当前**视图发一次 navigate('/login/', {reloadAll: true})。
每次 reloadAll 又让其他几个重新挂载,再各发一次——登录表单被持续拆掉重建,
根本打不出字。关掉页面过渡动画后这个循环变紧,症状才明显起来。
判断登录与否是外壳的职责,不是每个页面各自抢着跳转:
- App 持有会话状态:没有会话就只渲染一个 /login/ 视图,连 Tab 栏都不出;
有会话才渲染五个 Tab。
- Screen 不再做任何跳转。
- setSession / clearSession 派发 ghl:auth 事件。storage 事件只在**其他**
标签页触发,同标签页的登录登出需要自己的信号。
- 登录成功后不再手动 navigate:外壳会换掉整个视图,从一个正要被卸载的
视图里发起路由是在和它抢。
实测:登出后登录页只有 1 个视图、无 Tab 栏,输入的内容 2.5 秒后仍在,
且输入框还是同一个 DOM 节点(没有重挂);恢复会话后自动切回 5 个 Tab。
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import Framework7 from 'framework7/lite-bundle';
|
||||
import Framework7React from 'framework7-react';
|
||||
|
||||
import routes from './routes';
|
||||
import { apiClient, AUTH_EVENT } from './services/api';
|
||||
|
||||
import 'framework7/css/bundle';
|
||||
// The icon font F7's iconIos/iconMd props reference; without it the props
|
||||
@@ -217,8 +218,35 @@ function useRouterWatchdog() {
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether there is a session, kept live for this tab.
|
||||
*
|
||||
* The gate belongs to the shell, not to each screen. It used to live in
|
||||
* `Screen`, which every one of the five tab views renders at once — so a
|
||||
* logged-out start had all five firing `navigate('/login/', {reloadAll:true})`
|
||||
* at the same view, each reload remounting the others. The login form was
|
||||
* being torn down and rebuilt continuously and could not be typed into.
|
||||
*/
|
||||
function useSession() {
|
||||
const [authed, setAuthed] = useState(() => apiClient.isAuthenticated());
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setAuthed(apiClient.isAuthenticated());
|
||||
// `storage` covers other tabs; AUTH_EVENT covers this one.
|
||||
window.addEventListener('storage', check);
|
||||
window.addEventListener(AUTH_EVENT, check);
|
||||
return () => {
|
||||
window.removeEventListener('storage', check);
|
||||
window.removeEventListener(AUTH_EVENT, check);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return authed;
|
||||
}
|
||||
|
||||
function App() {
|
||||
useTheme();
|
||||
const authed = useSession();
|
||||
useClearBootFlag();
|
||||
useRouterWatchdog();
|
||||
const navigating = useNavProgress();
|
||||
@@ -235,6 +263,10 @@ function App() {
|
||||
routes={routes}
|
||||
touch={{ tapHold: true }}
|
||||
>
|
||||
{!authed ? (
|
||||
/* One view, no tab bar: there is nothing to navigate to yet. */
|
||||
<View main url="/login/" className="safe-areas" animate={false} />
|
||||
) : (
|
||||
<Views tabs className="safe-areas">
|
||||
<Toolbar tabbar icons bottom>
|
||||
{TABS.map((tab) => (
|
||||
@@ -280,6 +312,7 @@ function App() {
|
||||
/>
|
||||
))}
|
||||
</Views>
|
||||
)}
|
||||
</F7App>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user