-1

I'm working on a React application and I'm trying to listen to back button click events so I can customize the navigation flow. I've created the following hook:

export default function useBackButton(
  goTo: string,
) {
  const navigate = useNavigate();
  useEffect(() => {
    window.history.pushState(null, "", document.URL);
    window.addEventListener("popstate", backButtonHandler);
    return () => window.removeEventListener("popstate", backButtonHandler);
  });
  function backButtonHandler(event) {
      navigate(goTo, { replace: true });
    }
  }

The problem with the code is that the callback method "backButtonHandler" in ...

window.addEventListener("popstate", backButtonHandler);

... will not be invoked.

It will only work if I add it as inline logic:

 window.addEventListener("popstate", (event) => navigate(goTo, { replace: true });

I my case I need to provide the logic through a method declaration since I need to remove the listener.

Thanks in advance.

arif
  • 97
  • 1
  • 11

2 Answers2

1

You're forgetting a dependency array in your useEffect. This leads the event listener to be added and removed on each render. Just add an empty array as a dependency.

krirkrirk
  • 427
  • 1
  • 3
  • 8
0

If you need to listen to back button events you can create a function like this:

 const BackButtonListener = ({ children }) => {
  const [pressed, setPressed] = React.useState(false)
  React.useEffect(() => {
    window.onpopstate = e => {
      setPressed(true)
    };
  });
 return (
    <h3>Back button: {pressed.toString()}</h3>
  );
};

Then, include the same in your component as follows:

export default function App() {
  return (
    <Router>
      <div>
        ...
        <BackButtonListener />
        ...
      </div>
    </Router>
  );
}

Reference link: Intercept/handle browser's back button in React-router

inkredusk
  • 919
  • 4
  • 16