Intercept/handle browser's back button in React-router?

Solution 1:

This is a bit old question and you've probably already got your answer, but for people like me who needed this, I'm leaving this answer.

Using react-router made the job simple as such:

import { browserHistory } from 'react-router';

componentDidMount() {
    super.componentDidMount();

    this.onScrollNearBottom(this.scrollToLoad);

    this.backListener = browserHistory.listen(location => {
      if (location.action === "POP") {
        // Do your stuff
      }
    });
  }

componentWillUnmount() {
    super.componentWillUnmount();
    // Unbind listener
    this.backListener();
}

Solution 2:

Using hooks you can detect the back and forward buttons

import { useHistory } from 'react-router-dom'


const [ locationKeys, setLocationKeys ] = useState([])
const history = useHistory()

useEffect(() => {
  return history.listen(location => {
    if (history.action === 'PUSH') {
      setLocationKeys([ location.key ])
    }

    if (history.action === 'POP') {
      if (locationKeys[1] === location.key) {
        setLocationKeys(([ _, ...keys ]) => keys)

        // Handle forward event

      } else {
        setLocationKeys((keys) => [ location.key, ...keys ])

        // Handle back event

      }
    }
  })
}, [ locationKeys, ])

Solution 3:

here is how I ended up doing it:

componentDidMount() {
    this._isMounted = true;
    window.onpopstate = ()=> {
      if(this._isMounted) {
        const { hash } = location;
        if(hash.indexOf('home')>-1 && this.state.value!==0)
          this.setState({value: 0})
        if(hash.indexOf('users')>-1 && this.state.value!==1)
          this.setState({value: 1})
        if(hash.indexOf('data')>-1 && this.state.value!==2)
          this.setState({value: 2})
      }
    }
  }

thanks everybody for helping lol

Solution 4:

Hooks sample

const {history} = useRouter();
  useEffect(() => {
    return () => {
      // && history.location.pathname === "any specific path")
      if (history.action === "POP") {
        history.replace(history.location.pathname, /* the new state */);
      }
    };
  }, [history])

I don't use history.listen because it doesn't affect the state

const disposeListener = history.listen(navData => {
        if (navData.pathname === "/props") {
            navData.state = /* the new state */;
        }
    });