react-router icon indicating copy to clipboard operation
react-router copied to clipboard

[Feature]: Previous pathname

Open lasse-instructr opened this issue 3 years ago • 1 comments

What is the new or updated feature that you are suggesting?

We can get the current pathname through the useLocation() hook.

I want to get the pathname for the last page visited for the usage of a back button.

navigate(-1) does not suffice, as I need to know the previous route to decide whether or not it makes sense to navigate back to.

I have implemented a simple context for this purpose, but it would be nice if it was provided through React Router:

export interface IPreviousPageContextData {
  previousPathname: string | undefined
  /** Is true if the previous page has the same origin as the current page */
  previousPageIsAppPage: boolean
  /** Is true when the previous page is lower in the path-tree */
  previousPageIsShallower: boolean
}

const PreviousPageContext = createContext<IPreviousPageContextData | undefined>(undefined)

interface IPreviousPageProps {
  children: React.ReactNode;
}

const PreviousPageProvider: React.FC<IPreviousPageProps> = ({ children }) => {
  const [currentPathname, setCurrentPathname] = useState<string | undefined>(undefined)
  const [previousPathname, setPreviousPathname] = useState<string | undefined>(undefined)
  const { pathname: pathnameState } = useLocation()

  useEffect(() => {
    // Guard
    if (currentPathname !== window.location.pathname) {
      // Update pathname
      if (currentPathname !== undefined) {
        setPreviousPathname(currentPathname)
      }
      setCurrentPathname(window.location.pathname)
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pathnameState])

  const providerValue = useMemo(() => ({
    previousPageIsAppPage: previousPathname !== undefined,
    previousPageIsShallower: previousPathname !== undefined && previousPathname.length < window.location.pathname.length,
    previousPathname,
  }), [previousPathname])

  return (
  // This component will be used to encapsulate the whole App,
  // so all components will have access to the Context
    <PreviousPageContext.Provider value={providerValue}>
      {children}
    </PreviousPageContext.Provider>
  )
}
export {
  PreviousPageContext,
  PreviousPageProvider,
}

I hope that you get the gist of it.

Note: If the previous route was outside the app we will not have access to the pathname. In this case, I think that the state variable should return undefined.

Why should this feature be included?

I believe it is a common use case that you want to know the previous route.

lasse-instructr avatar Nov 28 '22 09:11 lasse-instructr

I need similar feature too, because workaround with setting prop state to the component <Link /> is in my case impossible.

I need to resolve redirecting from Page A to Page B and clicking on the browser Back button => there is no way how to set state to location and store previous pathname.

My current workaround is similar to @lasse-instructr, but causing unnecessary rerender.

MatyCZ avatar Dec 09 '22 09:12 MatyCZ

I'm going to convert this to a discussion so it can go through our new Open Development process. Please upvote the new Proposal if you'd like to see this considered!

brophdawg11 avatar Jan 09 '23 22:01 brophdawg11