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

℡╲_俬逩灬. 提交于 2019-12-28 02:49:45

问题


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

    <Tab value={0} label="dashboard" containerElement={<Link to="/dashboard/home"/>}/>
    <Tab value={1} label="users" containerElement={<Link to="/dashboard/users"/>} />
  <Tab value={2} label="data" containerElement={<Link to="/dashboard/data"/>} />

If I'm currenlty visting dashboard/data and I click browser's back button I go (for example) to dashboard/users but the highlighted Tab still stays on dashboard/data (value=2)

I can change by setting state, but I don't know how to handle the event when the browser's back button is pressed?

I've found this:

window.onpopstate = this.onBackButtonEvent;

but this is called each time state is changed (not only on back button event)


回答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();
}



回答2:


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




回答3:


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);



回答4:


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
    }
}



回答5:


Hooks sample

    const { history } = useRouter();

useEffect(() => {
    return () => {
        if (history.action === "POP") // && history.location.pathname === "any specific path") {
            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 */;
        }
    });


来源:https://stackoverflow.com/questions/39342195/intercept-handle-browsers-back-button-in-react-router

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!