web-dev-qa-db-fra.com

Intercepter/gérer le bouton de retour du navigateur dans React-router?

J'utilise les onglets de Material-ui, qui sont contrôlés et je les utilise pour des liens (React-routeur) comme celui-ci:

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

Si je consulte actuellement le tableau de bord/les données et que je clique sur le bouton Précédent du navigateur, je vais (par exemple) au tableau de bord/aux utilisateurs, mais l'onglet sélectionné reste sur le tableau de bord/les données (valeur = 2)

Je peux changer en réglant l'état, mais je ne sais pas comment gérer l'événement lorsque le bouton Précédent du navigateur est enfoncé?

J'ai trouvé ceci:

window.onpopstate = this.onBackButtonEvent;

mais cela s'appelle chaque fois que l'état est changé (pas seulement sur l'événement de bouton de retour)

16
high incompetance

voici comment j'ai fini par le faire:

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

merci à tous pour aider lol

8
high incompetance

C'est une question un peu ancienne et vous avez probablement déjà obtenu votre réponse, mais pour les personnes comme moi qui en avaient besoin, je laisse cette réponse.

En utilisant react-router, le travail est simple:

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();
}
16
Jay Shin

La version 3.x de l'API React Router contient un ensemble d'utilitaires que vous pouvez utiliser pour exposer un événement de bouton "Précédent" avant qu'il ne soit enregistré dans l'historique du navigateur. Vous devez d'abord envelopper votre composant dans la withRouter() composant d'ordre supérieur . Vous pouvez ensuite utiliser la fonction setRouteLeaveHook(), qui accepte tout objet route avec une propriété path valide et une fonction de rappel.

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

J'ai utilisé withrouter hoc pour obtenir l'historique prop et simplement écrire une méthode ComponentDidMount ()

componentDidMount() {
    if (this.props.history.action === "POP") {
        // custom back button implementation
    }
}
0