React-Router Externer Link

113

Da ich React-Router verwende, um meine Routen in einer React-App zu verarbeiten, bin ich gespannt, ob es eine Möglichkeit gibt, zu einer externen Ressource umzuleiten.

Angenommen, jemand trifft:

example.com/privacy-policy

Ich möchte, dass es umgeleitet wird zu:

example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

Ich finde genau null Hilfe, um zu vermeiden, dass es in einfachem JS in meiner index.html geschrieben wird, die mit etwas geladen wird wie:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}
Eric Hodonsky
quelle
Welchen React Router verwenden Sie?
Tyler McGinnis
Ich benutze Version 3.x
Eric Hodonsky
1
Ändern Sie einfach window.location.href, um eine formelle Weiterleitung zu erhalten.
Amirhossein Mehrvarzi
2
@AmirhosseinMehrvarzi das hat eigentlich nichts zu bedeuten. Könnten Sie genauer sein oder ein Beispiel geben? Ich bin mir auch nicht sicher, ob Sie es bemerkt haben, aber diese Frage hat bereits eine akzeptierte Antwort, die sich mit React & React Router befasst, worum es bei der Frage ging.
Eric Hodonsky
1
@Relic Sie müssen dies als Ihre URL in Ihrem if-Zustand verwenden. Ich hatte vor ein paar Tagen ein ähnliches Problem und fand diesen Weg einfach und effektiv. Es wird sofort umgeleitet. Akzeptierte Antwort ist eine Routing-Lösung (die zwar gegen die
Routenprinzipien

Antworten:

170

Hier ist ein Einzeiler für die Verwendung von React Router zum Umleiten zu einem externen Link:

<Route path='/privacy-policy' component={() => { 
     window.location.href = 'https://example.com/1234'; 
     return null;
}}/>

Es verwendet das React pure Component-Konzept, um den Code der Komponente auf eine einzige Funktion zu reduzieren, die den Browser nicht rendert, sondern an eine externe URL weiterleitet.

Funktioniert sowohl auf React Router 3 als auch auf React Router 4.

Evgeny Lukianchikov
quelle
2
Dies funktioniert, aber ich suchte nach einer eleganteren skalierbaren Lösung. Sehen Sie, was ich mir ausgedacht habe, da ich mit Weiterleitungen für MobileApps usw. (Not ReactNative, wirklich native Apps) noch weiter gehen konnte. Was ich jetzt mache, ist nicht der richtige Weg, um mein Problem zu lösen, aber um dieses Problem zu lösen, schlage ich vor, dass Sie auch meine Lösung untersuchen, wenn auch nur aus einer anderen Perspektive.
Eric Hodonsky
1
Das ist in meinem Kopf nicht wirklich so sauber. Ich würde lieber ehrlich ein Ankertag verwenden. Zweitens, wenn Sie die Schaltfläche Zurück im Browser drücken, erhalten Sie die Route zurück, die dann zurück zu example.zendesk.com/hc/en-us/articles/…
Jonathan Rys
11
Verwenden Sie window.location.replace (' example.com' )
MattC
1
Keine der Antworten trifft zu, der ursprüngliche Beitrag fragte nur nach Client-Weiterleitungen, obwohl bekannt ist, dass es keine echte Weiterleitungsunterstützung vom Typ 301 oder 302 gibt.
Eric Hodonsky
50

Es ist nicht erforderlich, eine <Link />Komponente vom React-Router zu verwenden.

Wenn Sie zu einem externen Link wechseln möchten, verwenden Sie ein Ankertag.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
Diego Laciar
quelle
20
Das OP fragte, wie es programmatisch und nicht deklarativ zu tun sei
Eric Hodonsky,
13
Nicht verwandte & irreführende Antwort.
Priya Ranjan Singh
1
Wenn Sie dies verwenden, fügen Sie rel="noopener noreferrer"dem<a>
S ..
4
Gute Antwort, nicht jeder wird sich darum kümmern, solange es funktioniert.
FrankByte.com
39

Am Ende habe ich meine eigene Komponente gebaut. <Redirect> Es werden Informationen aus dem react-routerElement entnommen, damit ich sie in meinen Routen behalten kann. Sowie:

<Route
  path="/privacy-policy"
  component={ Redirect }
  loc="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies"
  />

Hier ist meine Komponente, falls jemand neugierig ist:

import React, { Component } from "react";

export class Redirect extends Component {
  constructor( props ){
    super();
    this.state = { ...props };
  }
  componentWillMount(){
    window.location = this.state.route.loc;
  }
  render(){
    return (<section>Redirecting...</section>);
  }
}

export default Redirect;

BEARBEITEN - HINWEIS: Dies ist mit react-router: 3.0.5, es ist in 4.x nicht so einfach

Eric Hodonsky
quelle
Sie MÜSSEN nichts tun, reagieren ist ein Framework, und ein Framework hat viel Wert. So geht's im Reaktionsrahmen. Das Browserverlaufsmodul, in das hier eingewickelt werden könnte, wird jedoch NICHT berücksichtigt, was dies noch nützlicher macht. Bitte beachten Sie auch, dass "window.location" 1999 erstellt wurde. Dies ist nur eine Möglichkeit, es für das clientseitige Routing zu Ihrer Routentabelle hinzuzufügen. Es ist keine "gute" Lösung.
Eric Hodonsky
In React-Router v4 können Sie Render statt Komponente verwenden
Irrech
3
@Irrech "Render statt Komponente" bedeutet nichts. Wenn Sie eine Antwort auf die Frage haben, fügen Sie diese bitte hinzu und geben Sie einige Details zur Implementierung an.
Eric Hodonsky
3
@ MuhammadUmer oder Sie verwenden einfach ein Ankertag. React-Router ist ziemlich streng für das Routing nur innerhalb Ihrer Anwendung gedacht. Sie können mit dieser Designentscheidung nicht einverstanden sein (ich weiß, dass ich es tue), aber es ist nicht "1999 besser gemacht", es ist einfach das gleiche.
Worc
20

Es muss kein Reaktionsrouter angefordert werden. Diese Aktion kann nativ ausgeführt werden und wird vom Browser bereitgestellt.

benutz einfach window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}
Alan
quelle
1
Diese Antwort ist unvollständig, erlaubt keine Abstraktion oder ihre Beziehung zum Router
Eric Hodonsky
8
Das ist das Ziel. Es muss kein Reaktionsrouter angefordert werden. Diese Aktion kann nativ ausgeführt werden und wird vom Browser bereitgestellt.
Alan
8

Mit der Link-Komponente des React-Routers können Sie das tun. In der " to " Requisite können Sie 3 Arten von Daten angeben:

  • ein Faden : Eine Zeichenfolgendarstellung des Link-Speicherorts, die durch Verketten der Eigenschaften Pfadname, Suche und Hash des Standorts erstellt wird.
  • ein Objekt : Ein Objekt, das eine der folgenden Eigenschaften haben kann:
    • Pfadname : Eine Zeichenfolge, die den Pfad darstellt, zu dem eine Verknüpfung hergestellt werden soll.
    • Suche : Eine Zeichenfolgendarstellung von Abfrageparametern.
    • Hash : Ein Hash, der in die URL eingefügt werden soll, z. B. # a-Hash.
    • state : Zustand, in dem der Standort beibehalten werden soll.
  • a function : Eine Funktion, an die der aktuelle Standort als Argument übergeben wird und die die Standortdarstellung als Zeichenfolge oder als Objekt zurückgeben soll

Für Ihr Beispiel (externer Link):

https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

Sie können Folgendes tun:

<Link to={{ pathname: "https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies" }} target="_blank" />

Sie können auch Requisiten übergeben, auf denen Sie sich befinden möchten, z. B. Titel, ID, Klassenname usw.

Víctor Daniel
quelle
1
Dies ist die einfachste Lösung und funktioniert gut.
hPNJ7MHTyg
5

Unter Verwendung einiger Informationen hier habe ich die folgende Komponente entwickelt, die Sie in Ihren Routenerklärungen verwenden können. Es ist kompatibel mit React Router v4.

Es verwendet Typoskript, sollte aber ziemlich einfach sein, um es in natives Javascript zu konvertieren:

interface Props {
  exact?: boolean;
  link: string;
  path: string;
  sensitive?: boolean;
  strict?: boolean;
}

const ExternalRedirect: React.FC<Props> = (props: Props) => {
  const { link, ...routeProps } = props;

  return (
    <Route
      {...routeProps}
      render={() => {
        window.location.replace(props.link);
        return null;
      }}
    />
  );
};

Und verwenden mit:

<ExternalRedirect
  exact={true}
  path={'/privacy-policy'}
  link={'https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies'}
/>
Jens Bodal
quelle
2

Ich hatte Glück damit:

  <Route
    path="/example"
    component={() => {
    global.window && (global.window.location.href = 'https://example.com');
    return null;
    }}
/>
Alex Billson
quelle
1

Ich glaube nicht, dass React-Router diese Unterstützung bietet. In der Dokumentation wird erwähnt

Eine <Umleitung> richtet eine Umleitung zu einer anderen Route in Ihrer Anwendung ein , um alte URLs beizubehalten.

Sie könnten stattdessen versuchen, etwas wie React-Redirect zu verwenden

Ytibrewala
quelle
1

Um Alans Antwort zu erweitern, können Sie ein Attribut erstellen <Route/>, das alle <Link/>mit "to" -Attributen, die "http:" oder "https:" enthalten, an die richtige externe Ressource umleitet .

Unten finden Sie ein Arbeitsbeispiel dafür, das direkt in Ihrem platziert werden kann <Router>.

<Route path={['/http:', '/https:']} component={props => {
  window.location.replace(props.location.pathname.substr(1)) // substr(1) removes the preceding '/'
  return null
}}/>
Sam Mckay
quelle
0

FÜR V3, obwohl es für V4 funktionieren kann. Ausgehend von Erics Antwort musste ich etwas mehr tun, z. B. die lokale Entwicklung, bei der 'http' in der URL nicht vorhanden ist. Ich leite auch zu einer anderen Anwendung auf demselben Server um.

Zur Router-Datei hinzugefügt:

import RedirectOnServer from './components/RedirectOnServer';

       <Route path="/somelocalpath"
          component={RedirectOnServer}
          target="/someexternaltargetstring like cnn.com"
        />

Und die Komponente:

import React, { Component } from "react";

export class RedirectOnServer extends Component {

  constructor(props) {
    super();
    //if the prefix is http or https, we add nothing
    let prefix = window.location.host.startsWith("http") ? "" : "http://";
    //using host here, as I'm redirecting to another location on the same host
    this.target = prefix + window.location.host + props.route.target;
  }
  componentDidMount() {
    window.location.replace(this.target);
  }
  render(){
    return (
      <div>
        <br />
        <span>Redirecting to {this.target}</span>
      </div>
    );
  }
}

export default RedirectOnServer;
MattC
quelle
-1

Wenn Sie mit Typoskript reagieren, wird eine Fehlermeldung angezeigt, da die Funktion ein Reaktionselement zurückgeben muss, nicht void. Also habe ich es auf diese Weise mit der Route-Render-Methode (und mit React Router v4) gemacht:

redirectToHomePage = (): null => {
    window.location.reload();
    return null;
  };    
<Route exact path={'/'} render={this.redirectToHomePage} />

Wo Sie stattdessen auch verwenden könnten window.location.assign(), window.location.replace()etc.

chezwhite
quelle
-2

Wenn Sie serverseitiges Rending verwenden, können Sie verwenden StaticRouter. Mit Ihrem contextas propsund dann Hinzufügen einer <Redirect path="/somewhere" />Komponente in Ihrer App. Die Idee ist, dass jedes Mal, wenn der React-Router mit einer Umleitungskomponente übereinstimmt, dem Kontext, den Sie an den statischen Router übergeben haben, etwas hinzugefügt wird, um Sie darüber zu informieren, dass Ihr Pfad mit einer Umleitungskomponente übereinstimmt. Jetzt, da Sie wissen, dass Sie eine Weiterleitung getroffen haben, müssen Sie nur noch überprüfen, ob dies die Umleitung ist, nach der Sie suchen. dann einfach durch den Server umleiten. ctx.redirect('https://example/com').

Rei Dien
quelle
Ich frage nach einer Möglichkeit, dies im Client zu tun. Es sollte eigentlich auf DNS-Ebene durchgeführt werden, wenn es richtig gemacht wird. Zweitens wäre in der ersten Serveranforderung. Da ich auf S3 hoste, gibt es keine serverseitige. Also stecke ich vorerst fest, bis unser Entwickler die Weiterleitung auf Service-Ebene durchführen kann.
Eric Hodonsky
Was Sie tun können, ist<Redirect push={ true } to="/pathtoredirect" />
Rei Dien
-4

Ich konnte eine Umleitung in React-Router-Dom wie folgt erreichen

<Route exact path="/" component={() => <Redirect to={{ pathname: '/YourRoute' }} />} />

In meinem Fall suchte ich nach einer Möglichkeit, Benutzer bei jedem Besuch der Stamm-URL http://myapp.coman eine andere Stelle in der App umzuleiten http://myapp.com/newplace. also hat das oben genannte geholfen.

Walwolke
quelle
2
Das OP gibt eindeutig an, dass er versucht, zu einer externen Ressource umzuleiten, nicht zu einer Route innerhalb derselben App.
Neets
Offensichtlich war ich spezifisch in Bezug auf meinen Anwendungsfall und ließ ihn fallen, wenn er ihn auf seinen anwenden konnte. Meine Lösung besagt in meiner App, dass er dies als Beispiel verwenden könnte.
Walecloud
1
Wenn Sie Ihren Anwendungsfall anderen vorstellen möchten, schreiben Sie bitte einen Blog darüber. Stackoverflow dient zur Beantwortung der Anfrage von Personen, nicht Ihres Anwendungsfalls. Der richtige Weg, um Ihren Anwendungsfall zu implementieren, ist - <Weiterleiten von = "/" nach = {{Pfadname: '/ YourRoute'}} />
Abhas