-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
useIsRouteActive does not tell you whether you are on the route or not, just that it's part of the active route events For when you need to know if you are on exactly a specific route (it's an index route/the end of the chain) use `useOnRoute`
- Loading branch information
Showing
5 changed files
with
142 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { renderHook } from "@testing-library/react"; | ||
import { createMemoryHistory } from "history"; | ||
import React from "react"; | ||
|
||
import { buildCreateRoute } from "./createRoute"; | ||
import { RoutingContext } from "./providers"; | ||
import { useOnRoute } from "./useOnRoute"; | ||
|
||
const createRoute = buildCreateRoute(() => createMemoryHistory<any>(), "/"); | ||
const fooRoute = createRoute.simpleRoute()({ | ||
event: "foo", | ||
url: "/", | ||
}); | ||
|
||
describe("useOnRoute", () => { | ||
it("returns false if the supplied route is not part of the activeRouteEvents in the routing context", () => { | ||
const { result } = renderHook(() => useOnRoute(fooRoute), { | ||
wrapper: ({ children }) => ( | ||
<RoutingContext.Provider value={{ activeRouteEvents: { current: [] } }}> | ||
{children} | ||
</RoutingContext.Provider> | ||
), | ||
}); | ||
|
||
expect(result.current).toBe(false); | ||
}); | ||
|
||
it("throws an error if not called within the RoutingContext", () => { | ||
expect(() => renderHook(() => useOnRoute(fooRoute))).toThrow(); | ||
}); | ||
|
||
it("returns false if the supplied route is part of the activeRouteEvents but not marked as an index event", () => { | ||
const { result } = renderHook(() => useOnRoute(fooRoute), { | ||
wrapper: ({ children }) => ( | ||
<RoutingContext.Provider | ||
value={{ | ||
activeRouteEvents: { | ||
current: [ | ||
{ | ||
type: "foo", | ||
meta: { indexEvent: false }, | ||
originalUrl: "", | ||
params: {}, | ||
query: {}, | ||
}, | ||
], | ||
}, | ||
}} | ||
> | ||
{children} | ||
</RoutingContext.Provider> | ||
), | ||
}); | ||
|
||
expect(result.current).toBe(false); | ||
}); | ||
|
||
it("returns true if the supplied route is part of the activeRouteEvents and marked as an index event", () => { | ||
const { result } = renderHook(() => useOnRoute(fooRoute), { | ||
wrapper: ({ children }) => ( | ||
<RoutingContext.Provider | ||
value={{ | ||
activeRouteEvents: { | ||
current: [ | ||
{ | ||
type: "foo", | ||
meta: { indexEvent: true }, | ||
originalUrl: "", | ||
params: {}, | ||
query: {}, | ||
}, | ||
], | ||
}, | ||
}} | ||
> | ||
{children} | ||
</RoutingContext.Provider> | ||
), | ||
}); | ||
|
||
expect(result.current).toBe(true); | ||
}); | ||
|
||
it("returns false if a different route is active and marked as an index event", () => { | ||
const { result } = renderHook(() => useOnRoute(fooRoute), { | ||
wrapper: ({ children }) => ( | ||
<RoutingContext.Provider | ||
value={{ | ||
activeRouteEvents: { | ||
current: [ | ||
{ | ||
type: "bar", | ||
meta: { indexEvent: true }, | ||
originalUrl: "", | ||
params: {}, | ||
query: {}, | ||
}, | ||
], | ||
}, | ||
}} | ||
> | ||
{children} | ||
</RoutingContext.Provider> | ||
), | ||
}); | ||
|
||
expect(result.current).toBe(false); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { AnyRoute, type SharedMeta } from "./createRoute"; | ||
import { useActiveRouteEvents } from "./providers"; | ||
|
||
/** | ||
* @public | ||
* Accepts a single Route and returns true if the route is currently active and marked as an index route. | ||
* False if not. | ||
* | ||
* If used outside of a RoutingContext, an error will be thrown. | ||
* @param route - the route to check | ||
* @returns true if the route is active and an index route, false if not | ||
* @throws if used outside of an xstate-tree root | ||
*/ | ||
export function useOnRoute(route: AnyRoute): boolean { | ||
const activeRouteEvents = useActiveRouteEvents(); | ||
|
||
if (!activeRouteEvents) { | ||
throw new Error( | ||
"useOnRoute must be used within a RoutingContext. Are you using it outside of an xstate-tree Root?" | ||
); | ||
} | ||
|
||
return activeRouteEvents.some( | ||
(activeRouteEvent) => | ||
activeRouteEvent.type === route.event && | ||
(activeRouteEvent.meta as SharedMeta)?.indexEvent === true | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters