Как правильно реализовать глобальное перенаправление/защиту навигации в Expo Router?Javascript

Форум по Javascript
Ответить
Anonymous
 Как правильно реализовать глобальное перенаправление/защиту навигации в Expo Router?

Сообщение Anonymous »

Я пытаюсь реализовать глобальный компонент в Expo Router для управления потоком навигации моего приложения.
Логика зависит от:
  • Состояния аутентификации
  • Завершил ли пользователь регистрацию
  • Прошел ли пользователь платный доступ
  • Некоторые группы маршрутов (вкладки), (настройки), (капсула)
  • и т. д.
Я попробовал решение, приведенное ниже, и хотя оно работает в большинстве случаев, иногда оно вызывает неожиданные ошибки навигации. Исправление этих ошибок отнимает много времени, поэтому мне интересно, является ли мой подход в корне неверным или мне следует следовать рекомендуемому шаблону.
Я прочитал официальную документацию Expo Router о перенаправлениях, но они недостаточно подробны для многоуровневой логики, такой как аутентификация/онбординг/платный доступ и т. д.
Вот моя текущая реализация:

Код: Выделить всё

// Redirector.tsx
import { useAuth } from "@/hooks/useAuth";
import { getHasOnboarded, getHasPaywalled } from "@/utils/storage";
import {
Redirect,
usePathname,
useRootNavigationState,
useSegments,
} from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { useEffect, useMemo, useState } from "react";

SplashScreen.preventAutoHideAsync().catch(() => {});

const Redirector = ({ children }: { children: React.ReactElement }) => {
const [hasOnboarded, setHasOnboarded] = useState(
undefined
);
const [hasPaywalled, setHasPaywalled] = useState(
undefined
);
const { auth, loading } = useAuth();
const pathname = usePathname();
const navState = useRootNavigationState();
const segments = useSegments();

useEffect(() => {
(async () => {
const hasO = await getHasOnboarded();
const hasP = await getHasPaywalled();
setHasOnboarded(hasO);
setHasPaywalled(hasP);
})();
}, []);

const ready = useMemo(
() =>
Boolean(navState?.key) &&
!loading &&
hasOnboarded !== undefined &&
hasPaywalled !== undefined,
[navState?.key, loading, hasOnboarded, hasPaywalled]
);

useEffect(() => {
if (ready) {
SplashScreen.hideAsync().catch(() => {});
}
}, [ready]);

const onOnboarding = pathname.startsWith("/onboarding");
const onPaywalling = pathname.startsWith("/paywall");
const onTabs = segments[0] === "(tabs)";
const onCapsule = segments[0] === "(capsule)";
const onSettings = segments[0] === "(settings)";
const onAuth =
pathname.startsWith("/register") ||
pathname.startsWith("/forgot-password") ||
pathname.startsWith("/login");
const onLogin = pathname.startsWith("/login");

if (!navState?.key || loading) {
return null;
}

if (!hasOnboarded && !onPaywalling) {
if (!onOnboarding) return ;
return children;
}

if (!auth && hasOnboarded && !hasPaywalled) {
if (!onPaywalling) return ;
return children;
}

if (auth && !onPaywalling && !onCapsule && !onSettings) {
if (!onTabs) return ;
return children;
}

if (!auth && hasOnboarded && !onAuth && hasPaywalled) {
if (!onLogin) return ;
return children;
}

return children;
};

export default Redirector;
И я использую его в RootLayout следующим образом:

Код: Выделить всё

// _layout.tsx
...



...



...
Мой вопрос
Каков правильный или рекомендуемый способ реализации глобальной логики перенаправления (аутентификация/онбординг/платный доступ) в Expo Router?
Существует ли более надежный шаблон или лучший способ обработки этих потоков без возникновения несогласованности навигации?>

Подробнее здесь: https://stackoverflow.com/questions/798 ... xpo-router
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»