Fall back to push/replace behavior when navigate(-1)
would leave the website
#9922
Replies: 4 comments 2 replies
-
Yeah that sounds reasonable. I usually do it in the app by checking if the location key is "default" though. Maybe we just need to document this UX edge case better? <div>
{location.key !== "default" && (
<button onClick={() => navigate(-1)}>Back</button>
)}
</div> |
Beta Was this translation helpful? Give feedback.
-
i wrote this custom hook for export const useGoBack = () => {
const location = useLocation();
const navigate = useNavigate();
const thereIsAPrevPage = location.key !== "default";
if (thereIsAPrevPage) {
return (_arg: { fallback?: string }) => navigate(-1);
} else {
return ({ fallback }: { fallback?: string }) => navigate(fallback || "/");
}
};
// usage
const goBack = useGoBack()
// example with default fallback
onClick={() => goBack({})}
// example with custom fallback
onClick={() => goBack({fallBack: "/hello"})} |
Beta Was this translation helpful? Give feedback.
-
I'd expect some count to know how much we can go back / forward, like: const [historyLength, futureLength] = useHistory();
// maybe
const navHistory: { prev: Location[], next: Location[] } = useNavigationHistory();
// or
const { back, forward }: { back: Location[], forward: Location[] } = useLocation(); then another option would be to pass a function to the navigate, like so: navigate(({back, forward}) => back ? -1 : '/') the browser history api only provides .go(), and not history state, to prevent sites from spying on users, but within React Router which is single site specific, it makes sense |
Beta Was this translation helpful? Give feedback.
-
actually, when I think of it, it seems ideal to add back: Location[], forward: Location[] to useLocation(), and just allow callback to navigate(): navigate(({back}: UsedLocation) => back ? -1 : "/")
// or as second param if you don't want to add it to useLocation:
navigate((_, { back }) => back ? -1 : "/"); |
Beta Was this translation helpful? Give feedback.
-
First demonstration:
window.back()
.Second demonstration:
window.back()
(which would make you leave Twitter), a new history entry will be pushed.I believe React Router should support the same behavior. It's terrible UX to press the back button (or even worse, a close button in a route-based form like https://twitter.com/compose/tweet) and end up leaving the website.
So I propose that the following code is supported:
First, React Router must track the index of each history entry (as already happened before v6.4). Whenever a new history entry is pushed, set its state to contain
idx: prevIdx + 1
. When the current history entry is replaced, keep the sameidx
. Then, innavigate
, just check:It's a low-hanging fruit that will enable a much better UX for apps using React Router. In the future, we'll be able to do
window.navigation.canGoBack
with the Navigation API, but support is narrow today, so we have to work with what we have.Related issue: #9301
Beta Was this translation helpful? Give feedback.
All reactions