Wie rufe ich Link im React-Router manuell auf?

Lesezeit: 8 Minuten

Benutzeravatar von Alan Souza
Alan Suza

Ich habe eine Komponente, die durch Requisiten a empfängt <Link/> Objekt aus reagieren-router. Immer wenn der Benutzer innerhalb dieser Komponente, die ich aufrufen möchte, auf eine Schaltfläche „Weiter“ klickt <Link/> Objekt manuell.

Im Moment verwende ich Refs um auf die zuzugreifen Sicherungsinstanz und manuell auf das ‘a’-Tag klicken, das <Link/> erzeugt.

Frage: Gibt es eine Möglichkeit, den Link manuell aufzurufen (z this.props.next.go)?

Dies ist der aktuelle Code, den ich habe:

//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />

//in Document.js
...
var Document = React.createClass({
   _onClickNext: function() {
      var next = this.refs.next.getDOMNode();
      next.querySelectorAll('a').item(0).click(); //this sounds like hack to me
   },
   render: function() {
      return (
         ...
         <div ref="next">{this.props.next} <img src="rightArrow.png" onClick={this._onClickNext}/></div>
         ...
      );
   }
});
...

Dies ist der Code, den ich haben möchte:

//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />

//in Document.js
...
var Document = React.createClass({
   render: function() {
      return (
         ...
         <div onClick={this.props.next.go}>{this.props.next.label} <img src="rightArrow.png" /> </div>
         ...
      );
   }
});
...

Benutzeravatar von Matt Lo
Matt Lo

React Router v6 – React 17+ (aktualisiert am 14.01.2022)

import React, {useCallback} from 'react';
import {useNavigate} from 'react-router-dom';

export default function StackOverflowExample() {
  const navigate = useNavigate();
  const handleOnClick = useCallback(() => navigate('/sample', {replace: true}), [navigate]);

  return (
    <button type="button" onClick={handleOnClick}>
      Go home
    </button>
  );
}

Hinweis: Für diese Antwort ist die einzige wesentliche Änderung zwischen v6 und v5 useNavigate ist jetzt der bevorzugte React-Hook. useHistory ist veraltet und wird nicht empfohlen.

React Router v5 – React 16.8+ mit Hooks

Wenn Sie nutzen Haken reagierenkönnen Sie die nutzen useHistory API, die von React Router v5 stammt.

import React, {useCallback} from 'react';
import {useHistory} from 'react-router-dom';

export default function StackOverflowExample() {
  const history = useHistory();
  const handleOnClick = useCallback(() => history.push('/sample'), [history]);

  return (
    <button type="button" onClick={handleOnClick}>
      Go home
    </button>
  );
}

Eine andere Möglichkeit, den Click-Handler zu schreiben, wenn Sie ihn nicht verwenden möchten useCallback

const handleOnClick = () => history.push('/sample');

React Router v4 – Umleitungskomponente

Der für v4 empfohlene Weg besteht darin, Ihrer Rendermethode zu erlauben, eine Umleitung abzufangen. Verwenden Sie state oder props, um zu bestimmen, ob die Umleitungskomponente angezeigt werden muss (was dann eine Umleitung auslöst).

import { Redirect } from 'react-router';

// ... your class implementation

handleOnClick = () => {
  // some action...
  // then redirect
  this.setState({redirect: true});
}

render() {
  if (this.state.redirect) {
    return <Redirect push to="/sample" />;
  }

  return <button onClick={this.handleOnClick} type="button">Button</button>;
}

Bezug: https://reacttraining.com/react-router/web/api/Redirect

React Router v4 – Referenz-Router-Kontext

Sie können auch profitieren Router‘s-Kontext, der für die React-Komponente verfügbar gemacht wird.

static contextTypes = {
  router: PropTypes.shape({
    history: PropTypes.shape({
      push: PropTypes.func.isRequired,
      replace: PropTypes.func.isRequired
    }).isRequired,
    staticContext: PropTypes.object
  }).isRequired
};

handleOnClick = () => {
  this.context.router.push('/sample');
}

Das ist wie <Redirect /> arbeitet unter der Haube.

Bezug: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js#L46,L60

React Router v4 – Verlaufsobjekt extern mutieren

Wenn Sie noch etwas Ähnliches wie die Implementierung von v2 tun müssen, können Sie eine Kopie von erstellen BrowserRouter dann aussetzen history als exportierbare Konstante. Unten ist ein einfaches Beispiel, aber Sie können es zusammenstellen, um es bei Bedarf mit anpassbaren Requisiten zu versehen. Es gibt Hinweise zu Lebenszyklen, aber der Router sollte immer neu gerendert werden, genau wie in v2. Dies kann für Weiterleitungen nach einer API-Anforderung von einer Aktionsfunktion nützlich sein.

// browser router file...
import createHistory from 'history/createBrowserHistory';
import { Router } from 'react-router';

export const history = createHistory();

export default class BrowserRouter extends Component {
  render() {
    return <Router history={history} children={this.props.children} />
  }
}

// your main file...
import BrowserRouter from './relative/path/to/BrowserRouter';
import { render } from 'react-dom';

render(
  <BrowserRouter>
    <App/>
  </BrowserRouter>
);

// some file... where you don't have React instance references
import { history } from './relative/path/to/BrowserRouter';

history.push('/sample');

Neueste BrowserRouter erweitern: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

Reaktionsrouter v2

Schieben Sie einen neuen Zustand in die browserHistory Beispiel:

import {browserHistory} from 'react-router';
// ...
browserHistory.push('/sample');

Bezug: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md

  • hashHistory.push(‘/sample’); wenn Sie hashHistory anstelle von browserHistory verwenden

    – sanath_p

    21. Dezember 2016 um 22:40 Uhr

  • Dies ist besonders nützlich in der Material-UI-Bibliothek, da die Verwendung von containerElement={} nicht immer den Link aufruft

    – Vishal Disawar

    28. Januar 2017 um 6:07 Uhr

  • Beachten Sie, dass Sie bei der Weiterleitungsoption push angeben müssen (dh ). Standardmäßig wird es eine Ersetzung durchführen, was überhaupt nicht dasselbe ist wie das manuelle Aufrufen eines Links

    – aw04

    3. Mai 2017 um 15:28 Uhr


  • @jokab Sie können anstelle von verwenden github.com/ReactTraining/react-router/blob/master/packages/…

    – Matt Lo

    19. September 2017 um 3:57 Uhr

  • Die Umleitung funktioniert bei mir nicht, aber die aw04-Lösung mit withRouter ist einfacher und funktioniert

    – Stackdave

    10. Juni 2018 um 5:35 Uhr

Benutzeravatar von aw04
aw04

React Router 4 enthält a mitRouter HOC das gibt Ihnen Zugriff auf die history Objekt über this.props:

import React, {Component} from 'react'
import {withRouter} from 'react-router-dom'

class Foo extends Component {
  constructor(props) {
    super(props)

    this.goHome = this.goHome.bind(this)
  }

  goHome() {
    this.props.history.push("https://stackoverflow.com/")
  }

  render() {
    <div className="foo">
      <button onClick={this.goHome} />
    </div>
  }
}

export default withRouter(Foo)

  • Das hat bei mir funktioniert und es sieht nach der einfachsten Lösung aus.

    – Rubinschnitt

    27. Juni 2017 um 12:29 Uhr

  • Dies ist die beste Lösung. Ich verstehe nicht, warum es so wenige Stimmen hat.

    – Benoît

    5. November 2017 um 21:50 Uhr

  • Ja, Sie können einige Male auf den Link klicken und der Browser-Zurück funktioniert nicht. Sie müssen einige Male auf Browser zurück klicken, um wirklich zurückzugehen

    – Vladyslaw Tereschyn

    4. März 2019 um 10:42 Uhr

  • @VladyslavTereshyn Sie können eine bedingte Logik hinzufügen: if ((this.props.location.pathname + this.props.location.search) !== NavigatoPath) { … }

    – Matt Weiler

    20. April 2020 um 14:16 Uhr


  • Nach einer Stunde Suche hat diese Lösung endlich funktioniert. Danke dir!

    – IonicMan

    17. August 2021 um 15:47 Uhr

Benutzeravatar von Paulo Mateus
Paul Mateus

Im Version 5.xkönnen Sie verwenden useHistory Haken von react-router-dom:

// Sample extracted from https://reacttraining.com/react-router/core/api/Hooks/usehistory
import { useHistory } from "react-router-dom";

function HomeButton() {
  const history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

  • Dies ist die beste Lösung. Wenn Sie eine bedingte Logik hinzufügen, können Sie doppelte Einträge im Verlauf vermeiden, wenn ein Benutzer mehrmals auf dieselbe Schaltfläche klickt: if ((routerHistory.location.pathname + routerHistory.location.search) !== navigateToPath) { routerHistory.push(navigateToPath); }

    – Matt Weiler

    20. April 2020 um 15:37 Uhr

  • Ich musste deklarieren history Variable, Verzeichnisaufruf useHistory().push ist nach Hooks-Regeln nicht erlaubt

    – onmyway133

    2. Juni 2020 um 16:00 Uhr

  • Dies scheint die modernste reaktionsfreudige Lösung zu sein.

    – Youngjae

    30. Juli 2020 um 9:50 Uhr

  • Das ist ordentlich 👌und funktioniert natürlich auch für v5.x Mit Pfeilfunktionen könnte man einfach weiter so onClick={ () => history.push('/home') }

    – KeshavDulal

    23. September 2020 um 6:37 Uhr


Benutzeravatar von grechut
Grechut

https://github.com/rackt/react-router/blob/bf89168acb30b6dc9b0244360bcbac5081cf6b38/examples/transitions/app.js#L50

oder Sie können sogar versuchen, onClick this auszuführen (gewalttätigere Lösung):

window.location.assign("/sample");

Antworten hier sind veraltet.

Reaktionsrouter 6

useHistory ist veraltet v6 verwendet die useNavigate Haken statt.

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

const navigate = useNavigate()

navigate(`/somewhere`, { replace: true })

Ok, ich glaube, ich konnte eine passende Lösung dafür finden.

Jetzt, anstatt zu senden <Link/> als Stütze zum Dokument sende ich <NextLink/> Dies ist ein benutzerdefinierter Wrapper für den React-Router-Link. Auf diese Weise kann ich den rechten Pfeil als Teil der Link-Struktur haben und gleichzeitig vermeiden, Routing-Code im Document-Objekt zu haben.

Der aktualisierte Code sieht wie folgt aus:

//in NextLink.js
var React = require('react');
var Right = require('./Right');

var NextLink = React.createClass({
    propTypes: {
        link: React.PropTypes.node.isRequired
    },

    contextTypes: {
        transitionTo: React.PropTypes.func.isRequired
    },

    _onClickRight: function() {
        this.context.transitionTo(this.props.link.props.to);
    },

    render: function() {
        return (
            <div>
                {this.props.link}
                <Right onClick={this._onClickRight} />
            </div>  
        );
    }
});

module.exports = NextLink;

...
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
var nextLink = <NextLink link={sampleLink} />
<Document next={nextLink} />

//in Document.js
...
var Document = React.createClass({
   render: function() {
      return (
         ...
         <div>{this.props.next}</div>
         ...
      );
   }
});
...

PS: Wenn Sie die neueste Version von React-Router verwenden, müssen Sie möglicherweise verwenden this.context.router.transitionTo anstatt this.context.transitionTo. Dieser Code funktioniert gut für die React-Router-Version 0.12.X.

Benutzeravatar von Chris
Chris

Reaktionsrouter 4

Sie können die Push-Methode in v4 einfach über den Kontext aufrufen:

this.context.router.push(this.props.exitPath);

wo Kontext ist:

static contextTypes = {
    router: React.PropTypes.object,
};

  • Verwenden BrowserRouterenthält das Kontextobjekt meiner Komponenten kein a router Objekt. Mache ich etwas falsch?

    – Pilau

    1. März 2017 um 17:54 Uhr

  • Setzen Sie den Kontext in der Komponente (zweiter Block oben)?

    – Chris

    2. März 2017 um 0:00 Uhr

  • Danke fürs Mitmachen! schließlich hat das bei mir funktioniert: router: React.PropTypes.object.isRequired. Ich weiß nicht, warum es ohne nicht funktioniert hat isRequired Schlüssel. Ebenfalls, <Link> scheint in der Lage zu sein, die zu bekommen history Kontext, aber ich konnte es nicht replizieren.

    – Pilau

    2. März 2017 um 13:36 Uhr

  • Interessant – wenn Sie einen Codepen aufstellen, könnte ich Ihnen helfen, ihn zu debuggen, wenn Sie immer noch feststecken

    – Chris

    2. März 2017 um 13:49 Uhr

  • Es scheint, als könnten Sie verwenden this.props.history.push() im React-Router v4. Ich habe dies nur gefunden, indem ich die Requisiten untersucht habe, die React Router eingibt. Es scheint zu funktionieren, aber ich bin mir nicht sicher, ob es eine gute Idee ist.

    – sean_j_roberts

    16. März 2017 um 14:51 Uhr

1439080cookie-checkWie rufe ich Link im React-Router manuell auf?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy