T
TanStack13mo ago
conscious-sapphire

How to block, if user wants to leave a route-tree?

Hey 👋🏽 @Sean Cassiere @Tanner Linsley , I have a create-order route with multiple steps. So the route-tree looks like this: create-order/step-1 create-order/step-2 A state-object is created in the individual steps. Each step must be run through in order to make a server request at the end. If the user now runs through the steps, I would like to implement a blocking if the user wants to leave the create-order-route. I tried to use useBlocker at create-order/route.jsx
export const Route = createFileRoute("/app/create-order")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: Component,
});

function Component() {
useBlocker({
blockerFn: (props) => {
console.log(props); //logs undefined
return window.confirm("Are you sure you want to leave?");
},
condition: true,
});
}
export const Route = createFileRoute("/app/create-order")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: Component,
});

function Component() {
useBlocker({
blockerFn: (props) => {
console.log(props); //logs undefined
return window.confirm("Are you sure you want to leave?");
},
condition: true,
});
}
But this does not work, because it is not known where the user is navigating to. In this case, a switch from step 1 to step 2 is also blocked. What options do we have here? Thanks!
7 Replies
old-apricot
old-apricot13mo ago
Maybe you could try moving the blocker down to the page you are navigating from. i.e. /create-order/step-1
old-apricot
old-apricot13mo ago
Or, for the condition you can get the current location using the useLocation hook and conditionally make it truthy. https://tanstack.com/router/latest/docs/framework/react/api/router/useLocationHook
useLocation hook | TanStack Router React Docs
The useLocation method is a hook that returns the current location object. This hook is useful for when you want to perform some side effect whenever the current location changes. useLocation options
conscious-sapphire
conscious-sapphireOP13mo ago
Thanks @Sean Cassiere Moving the blocker down to the steps does not work. The user should be blocked from moving away from create-order/*, so i.e. from create-order/step-5 to orders should be blocked. Navigation within the steps is fine. Unfortunately useLocation does not work either, cause it just shows the current location. I need the location to be visited at the blocking time, then it would work.
// pseudo-code
const routerState = useRouterState();
useBlocker({
blockerFn: ({ from, to }) => {
return to !== 'create-order' && window.confirm("Are you sure you want to leave?");
},
});
// pseudo-code
const routerState = useRouterState();
useBlocker({
blockerFn: ({ from, to }) => {
return to !== 'create-order' && window.confirm("Are you sure you want to leave?");
},
});
Did I miss something? Is there no solution for this use case yet? I can't think of anything else. Thanks
conscious-sapphire
conscious-sapphireOP13mo ago
GitHub
feat: Update useBlocker hook to provide current and next location...
Currently, when using the useBlocker hook there is no way to ascertain where the navigation being blocked is headed. For my usage of blocking, this is necessary to allow navigation within a selecte...
conscious-sapphire
conscious-sapphireOP13mo ago
@Manuel Schiller Can we drive this PR forward?
genetic-orange
genetic-orange13mo ago
did you test the PR with your code? does it solve your issue?
conscious-sapphire
conscious-sapphireOP13mo ago
I had no time to test it in the last days. I think it would solve my usecase. Maybe I find some time next week.

Did you find this page helpful?