From 235634c6cded8b190c07b3ce64e82233af65a05d Mon Sep 17 00:00:00 2001 From: Georgi Todorov Date: Thu, 20 Jun 2024 11:04:31 +0300 Subject: [PATCH 1/2] Move navigation to machine --- src/contexts/useApp.tsx | 4 ++-- ...henticated.ts => authenticated.navigator.ts} | 10 ++++++++-- ...nticating.ts => authenticating.navigator.ts} | 0 src/machines/shared/actors.ts | 17 +++++++++++++++++ src/navigation/AuthenticatedNavigator.tsx | 7 +------ src/navigation/AuthenticatingNavigator.tsx | 7 +------ 6 files changed, 29 insertions(+), 16 deletions(-) rename src/machines/{authenticated.ts => authenticated.navigator.ts} (87%) rename src/machines/{authenticating.ts => authenticating.navigator.ts} (100%) create mode 100644 src/machines/shared/actors.ts diff --git a/src/contexts/useApp.tsx b/src/contexts/useApp.tsx index 001f9a0..1283206 100644 --- a/src/contexts/useApp.tsx +++ b/src/contexts/useApp.tsx @@ -4,11 +4,11 @@ import { createActorContext, useSelector } from "@xstate/react"; import { AuthenticatingMachineActor, authenticatingMachine, -} from "../machines/authenticating"; +} from "../machines/authenticating.navigator"; import { AuthenticatedMachineActor, authenticatedMachine, -} from "../machines/authenticated"; +} from "../machines/authenticated.navigator"; export const appMachine = setup({ types: { diff --git a/src/machines/authenticated.ts b/src/machines/authenticated.navigator.ts similarity index 87% rename from src/machines/authenticated.ts rename to src/machines/authenticated.navigator.ts index 7fcf529..4547552 100644 --- a/src/machines/authenticated.ts +++ b/src/machines/authenticated.navigator.ts @@ -1,7 +1,8 @@ -import { ActorRefFrom, setup, assign } from "xstate"; +import { ActorRefFrom, setup, assign, fromCallback } from "xstate"; import { AuthenticatedParamList } from "../types/navigation"; import { HomeMachineActor, homeMachine } from "./home"; import { ListMachineActor, listMachine } from "./list"; +import { navigationSubscriber } from "./shared/actors"; export type AuthenticatedMachineActor = ActorRefFrom< typeof authenticatedMachine @@ -27,7 +28,11 @@ export const authenticatedMachine = setup({ }, }), }, - actors: { homeMachine, listMachine }, + actors: { + homeMachine, + listMachine, + navigationSubscriber, + }, guards: { isHomeScreen(_, params: { screen: keyof AuthenticatedParamList }) { return params.screen === "Home"; @@ -40,6 +45,7 @@ export const authenticatedMachine = setup({ context: { refHome: undefined, refList: undefined }, id: "application", initial: "homeScreen", + invoke: { src: "navigationSubscriber" }, on: { NAVIGATE: [ { diff --git a/src/machines/authenticating.ts b/src/machines/authenticating.navigator.ts similarity index 100% rename from src/machines/authenticating.ts rename to src/machines/authenticating.navigator.ts diff --git a/src/machines/shared/actors.ts b/src/machines/shared/actors.ts new file mode 100644 index 0000000..b86e1be --- /dev/null +++ b/src/machines/shared/actors.ts @@ -0,0 +1,17 @@ +import { fromCallback } from "xstate"; +import { + getCurrentRouteName, + navigationRef, +} from "../../navigation/NavigationRef"; + +export const navigationSubscriber = fromCallback(({ sendBack }) => { + const unsubscribe = navigationRef.addListener("state", (_event) => { + const screenRoute = getCurrentRouteName(); + + if (screenRoute) { + sendBack({ type: "NAVIGATE", screen: screenRoute }); + } + }); + + return unsubscribe; +}); diff --git a/src/navigation/AuthenticatedNavigator.tsx b/src/navigation/AuthenticatedNavigator.tsx index 2d370ad..59ef3ee 100644 --- a/src/navigation/AuthenticatedNavigator.tsx +++ b/src/navigation/AuthenticatedNavigator.tsx @@ -6,10 +6,9 @@ import { AuthenticatedParamList, RootStackScreenProps, } from "../types/navigation"; -import { AuthenticatedMachineActor } from "../machines/authenticated"; +import { AuthenticatedMachineActor } from "../machines/authenticated.navigator"; import HomeScreen from "../screens/Home"; import ListScreen from "../screens/List"; -import { useNavigator } from "../hooks/useNavigator"; const Stack = createNativeStackNavigator(); @@ -22,10 +21,6 @@ export function AuthenticatedNavigator({ actorRef }: Props) { return snapshot; }); - useNavigator((route) => { - actorRef.send({ type: "NAVIGATE", screen: route }); - }); - return ( diff --git a/src/navigation/AuthenticatingNavigator.tsx b/src/navigation/AuthenticatingNavigator.tsx index 3ddc460..daff0d7 100644 --- a/src/navigation/AuthenticatingNavigator.tsx +++ b/src/navigation/AuthenticatingNavigator.tsx @@ -6,9 +6,8 @@ import { AuthenticatingParamList, RootStackScreenProps, } from "../types/navigation"; -import { AuthenticatingMachineActor } from "../machines/authenticating"; +import { AuthenticatingMachineActor } from "../machines/authenticating.navigator"; import SignInScreen from "../screens/SignIn"; -import { useNavigator } from "../hooks/useNavigator"; const Stack = createNativeStackNavigator(); @@ -21,10 +20,6 @@ export function AuthenticatingNavigator({ navigation, actorRef }: Props) { return snapshot; }); - useNavigator((route) => { - actorRef.send({ type: "NAVIGATE", screen: route }); - }); - return ( From 925002ec15d9ddc4312d1d4d1796ef5900e4b354 Mon Sep 17 00:00:00 2001 From: Georgi Todorov Date: Thu, 20 Jun 2024 11:08:07 +0300 Subject: [PATCH 2/2] Delete useNavigator --- src/hooks/useNavigator.ts | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/hooks/useNavigator.ts diff --git a/src/hooks/useNavigator.ts b/src/hooks/useNavigator.ts deleted file mode 100644 index f1aec4e..0000000 --- a/src/hooks/useNavigator.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useEffect, useRef } from "react"; -import { - getCurrentRouteName, - navigationRef, -} from "../navigation/NavigationRef"; - -export function useNavigator( - callback: (route: keyof T) => void, - initialRoute?: keyof T, -) { - const prevRoute = useRef(); - - useEffect(() => { - const unsubscribe = navigationRef.addListener("state", (_event) => { - const screenRoute = getCurrentRouteName(); - - if (screenRoute && prevRoute.current !== screenRoute) { - prevRoute.current = screenRoute; - callback(screenRoute as keyof T); - } else if (!screenRoute && initialRoute) { - callback(initialRoute); - } - }); - - return unsubscribe; - }, []); -}