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

前端 未结 12 1010
滥情空心
滥情空心 2020-11-27 03:47

I\'m using Material-ui\'s Tabs, which are controlled and I\'m using them for (React-router) Links like this:

    

        
相关标签:
12条回答
  • 2020-11-27 04:18

    For giving warning on the press of browser back in react functional components. do the following steps

    1. declare isBackButtonClicked and initialize it as false and maintain the state using setBackbuttonPress function.
    const [isBackButtonClicked, setBackbuttonPress] = useState(false);
    
    1. In componentdidmount, add the following lines of code
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', onBackButtonEvent);
    
    1. define onBackButtonEvent Function and write logic as per your requirement.

        const onBackButtonEvent = (e) => {
        e.preventDefault();
        if (!isBackButtonClicked) {
      
        if (window.confirm("Do you want to go to Test Listing")) {
          setBackbuttonPress(true)
          props.history.go(listingpage)
        } else {
          window.history.pushState(null, null, window.location.pathname);
          setBackbuttonPress(false)
        }
      }
      

      }

    2. In componentwillmount unsubscribe onBackButtonEvent Function

    Final code will look like this

    import React,{useEffect,useState} from 'react'
    
    function HandleBrowserBackButton() {
      const [isBackButtonClicked, setBackbuttonPress] = useState(false)
    
      useEffect(() => {
    
        window.history.pushState(null, null, window.location.pathname);
        window.addEventListener('popstate', onBackButtonEvent);
    
        //logic for showing popup warning on page refresh
        window.onbeforeunload = function () {
    
          return "Data will be lost if you leave the page, are you sure?";
        };
        return () => {
          window.removeEventListener('popstate', onBackButtonEvent);
        }
    
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
      const onBackButtonEvent = (e) => {
        e.preventDefault();
        if (!isBackButtonClicked) {
    
          if (window.confirm("Do you want to go to Test Listing")) {
            setBackbuttonPress(true)
            props.history.go(listingpage)
          } else {
            window.history.pushState(null, null, window.location.pathname);
            setBackbuttonPress(false)
          }
        }
      }
    
      return (
        <div>
    
        </div>
      )
    }
    
    export default HandleBrowserBackButton
    
    0 讨论(0)
  • 2020-11-27 04:23

    I used withrouter hoc in order to get history prop and just write a componentDidMount() method:

    componentDidMount() {
        if (this.props.history.action === "POP") {
            // custom back button implementation
        }
    }
    
    0 讨论(0)
  • 2020-11-27 04:25

    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, ])
    
    0 讨论(0)
  • 2020-11-27 04:26

    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();
    }
    
    0 讨论(0)
  • 2020-11-27 04:26

    Version 3.x of the React Router API has a set of utilities you can use to expose a "Back" button event before the event registers with the browser's history. You must first wrap your component in the withRouter() higher-order component. You can then use the setRouteLeaveHook() function, which accepts any route object with a valid path property and a callback function.

    import {Component} from 'react';
    import {withRouter} from 'react-router';
    
    class Foo extends Component {
      componentDidMount() {
        this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave);
      }
    
      routerWillLeave(nextState) { // return false to block navigation, true to allow
        if (nextState.action === 'POP') {
          // handle "Back" button clicks here
        }
      }
    }
    
    export default withRouter(Foo);
    
    0 讨论(0)
  • 2020-11-27 04:26

    You can use "withrouter" HOC and use this.props.history.goBack.

    <Button onClick={this.props.history.goBack}>
        BACK
    </Button>
    
    0 讨论(0)
提交回复
热议问题