Collegamento esterno React-Router


113

Dato che utilizzo il router per gestire i miei percorsi in un'app, sono curioso di sapere se esiste un modo per reindirizzare a una risorsa esterna.

Di 'che qualcuno colpisce:

example.com/privacy-policy

Vorrei che reindirizzasse a:

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

Sto trovando esattamente zero aiuto nell'evitare di scriverlo in semplice JS al mio caricamento index.html con qualcosa del tipo:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}

Quale React Router stai usando?
Tyler McGinnis

Sto usando la versione 3.x
Eric Hodonsky

1
Basta cambiare window.location.hrefper avere un reindirizzamento formale.
Amirhossein Mehrvarzi

2
@AmirhosseinMehrvarzi che in realtà non significa nulla. Potresti essere più specifico o fare un esempio? Inoltre non sono sicuro che tu l'abbia notato, ma questa domanda ha già una risposta accettata che riguarda React & React Router, che è l'argomento della domanda.
Eric Hodonsky

1
@Relic Devi usarlo come URL nella tua condizione if. Ho avuto un problema simile qualche giorno fa e ho trovato questo modo semplice ed efficace. Reindirizza immediatamente. La risposta accettata è una soluzione di routing (sebbene viola i principi del percorso, considerando che l'architettura del percorso è per la navigazione all'interno dell'App non per l'esterno) che non funziona per nessun ambiente come il mio
Amirhossein Mehrvarzi

Risposte:


170

Ecco una riga per utilizzare React Router per reindirizzare a un collegamento esterno:

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

Utilizza il concetto di componente puro di React per ridurre il codice del componente a una singola funzione che, invece di rendere qualsiasi cosa, reindirizza il browser a un URL esterno.

Funziona sia su React Router 3 che su 4.


2
Funziona ma stavo cercando una soluzione scalabile più elegante. Guarda cosa ho trovato in quanto mi ha permesso di andare ancora oltre con i reindirizzamenti per MobileApps ecc. (Non ReactNative, app veramente native). Quello che sto facendo non è il modo giusto per risolvere il mio problema, ma per risolvere questo problema ti suggerisco di indagare anche sulla mia soluzione se non altro che una prospettiva diversa.
Eric Hodonsky,

1
Non è così pulito nella mia mente. Preferirei usare un tag di ancoraggio onestamente. In secondo luogo, premendo il pulsante Indietro sul browser viene restituito il percorso che quindi reindirizza a example.zendesk.com/hc/en-us/articles/…
Jonathan Rys

11
Per un migliore comportamento del pulsante Indietro (verifica per la tua applicazione), usa window.location.replace (' example.com' )
MattC

1
Nessuna delle risposte lo fa, il post originale chiedeva solo i reindirizzamenti dei client, MENTRE sapendo che non esiste un supporto di reindirizzamento vero di tipo 301 o 302.
Eric Hodonsky

50

Non è necessario utilizzare <Link />componenti da React-Router.

Se vuoi andare su un link esterno usa un anchor tag.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>

20
L'OP chiedeva come farlo in modo programmatico, non dichiarativo
Eric Hodonsky

13
Risposta non correlata e fuorviante.
Priya Ranjan Singh

1
Se lo usi, aggiungi rel="noopener noreferrer"a<a>
S ..

5
Buona risposta, non a tutti importerà finché lo faranno funzionare.
FrankByte.com

39

In realtà ho finito per costruire il mio componente. <Redirect> Prende informazioni react-routerdall'elemento in modo da poterlo conservare nei miei percorsi. Ad esempio:

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

Ecco il mio componente se qualcuno è curioso:

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;

EDIT - NOTA: Questo è con react-router: 3.0.5, non è così semplice in 4.x


non DEVI fare nulla, reagire è una struttura e c'è molto valore in una struttura. QUESTO è come farlo all'interno del framework React. Tuttavia NON tiene conto del modulo della cronologia del browser che potrebbe essere incluso qui, rendendolo ancora più utile. Nota anche che "window.location" è come è stato fatto nel 1999. Questo è solo un modo per aggiungerlo alla tua tabella delle rotte per il routing lato client. Non è una "buona" soluzione.
Eric Hodonsky

in react -router v4 puoi usare render invece componente
Irrech

3
@ Irrech "render invece componente" non significa nulla. Se hai una risposta alla domanda, aggiungila e fornisci alcuni dettagli su come implementarla.
Eric Hodonsky,

3
@MuhammadUmer o usi semplicemente un anchor tag. reagire-router è abbastanza strettamente inteso per il routing solo all'interno della tua applicazione. si può non essere d'accordo con questa decisione di progettazione (lo so io faccio), ma non è "fare meglio nel 1999", è solo fatto lo stesso.
worc

21

Non è necessario richiedere il router di reazione. Questa azione può essere eseguita in modo nativo ed è fornita dal browser.

basta usare window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}

1
Questa risposta è incompleta, non consente l'astrazione o la sua relazione con il router
Eric Hodonsky

8
Questo è l'obiettivo. Non è necessario richiedere il router di reazione. Questa azione può essere eseguita in modo nativo ed è fornita dal browser.
Alan

10

Con il componente Link di React-router puoi farlo. Nella prop " a " puoi specificare 3 tipi di dati:

  • una stringa : una rappresentazione di stringa della posizione del collegamento, creata concatenando il nome del percorso, la ricerca e le proprietà hash della posizione.
  • un oggetto : un oggetto che può avere una delle seguenti proprietà:
    • pathname : una stringa che rappresenta il percorso a cui collegarsi.
    • ricerca : una rappresentazione di stringa dei parametri di query.
    • hash : un hash da inserire nell'URL, ad esempio # a-hash.
    • state : stato per persistere nella posizione.
  • una funzione : una funzione alla quale viene passata la posizione corrente come argomento e che dovrebbe restituire la rappresentazione della posizione come stringa o come oggetto

Per il tuo esempio (link esterno):

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

Puoi fare quanto segue:

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

Puoi anche passare oggetti di scena su cui vorresti essere come titolo, id, className, ecc.


1
Questa è la soluzione più semplice e funziona bene.
hPNJ7MHTyg

5

Usando alcune delle informazioni qui, ho trovato il seguente componente che puoi usare nelle tue dichiarazioni di rotta. È compatibile con React Router v4.

Utilizza il dattiloscritto, ma dovrebbe essere abbastanza semplice da convertire in javascript nativo:

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

E usa con:

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

2

Ho avuto fortuna con questo:

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

1

Non credo che React-Router fornisca questo supporto. La documentazione menziona

Un <Redirect> imposta un reindirizzamento a un altro percorso nell'applicazione per mantenere i vecchi URL.

Potresti provare a usare qualcosa come React-Redirect invece


1

Per espandere la risposta di Alan, puoi creare un <Route/>che reindirizza tutto<Link/> attributi "a" contenenti "http:" o "https:" alla risorsa esterna corretta.

Di seguito è riportato un esempio funzionante di questo che può essere posizionato direttamente nel tuo file <Router>.

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

0

PER V3, sebbene possa funzionare per V4. Partendo dalla risposta di Eric, avevo bisogno di fare un po 'di più, come gestire lo sviluppo locale dove "http" non è presente nell'URL. Sto anche reindirizzando a un'altra applicazione sullo stesso server.

Aggiunto al file del router:

import RedirectOnServer from './components/RedirectOnServer';

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

E il componente:

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;

-1

Usando React with Typescript ottieni un errore in quanto la funzione deve restituire un elemento react, non void. Quindi l'ho fatto in questo modo usando il metodo di rendering del percorso (e usando il router React v4):

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

Dove potresti invece usare anche window.location.assign(), window.location.replace()ecc


-2

Se stai usando il rending lato server, puoi usare StaticRouter. Con il tuo contextas propse poi aggiungi il <Redirect path="/somewhere" />componente nella tua app. L'idea è che ogni volta che react-router corrisponde a un componente di reindirizzamento, aggiungerà qualcosa nel contesto passato al router statico per farti sapere che il tuo percorso corrisponde a un componente di reindirizzamento. ora che sai di aver colpito un reindirizzamento, devi solo controllare se questo è il reindirizzamento che stai cercando. quindi reindirizza tramite il server. ctx.redirect('https://example/com').


Sto chiedendo un modo per farlo nel client. In realtà dovrebbe essere fatto a livello DNS se fatto correttamente. Il secondo sarebbe nella richiesta del server iniziale. Dato che sto ospitando su S3, non esiste un lato server. Quindi sono bloccato per ora fino a quando il nostro addetto agli sviluppatori non può fare il reindirizzamento al livello di servizio.
Eric Hodonsky

quello che puoi fare è,<Redirect push={ true } to="/pathtoredirect" />
Rei Dien

-4

Sono stato in grado di ottenere un reindirizzamento in react-router-dom utilizzando quanto segue

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

Nel mio caso, stavo cercando un modo per reindirizzare gli utenti ogni volta che visitano l'URL di root http://myapp.comda qualche altra parte all'interno dell'app http://myapp.com/newplace. quindi quanto sopra ha aiutato.


2
L'OP afferma chiaramente che sta cercando di reindirizzare a una risorsa esterna, non a un percorso all'interno della stessa app.
Neets

Chiaramente, ero specifico sul mio caso d'uso e l'ho lasciato cadere se poteva applicarlo al suo. la mia soluzione dice all'interno della mia app, potrebbe usarla come esempio.
walecloud

1
Se vuoi mostrare il tuo caso d'uso alle persone, scrivi un blog a riguardo. Stackoverflow serve per rispondere alla domanda che le persone hanno, non al tuo caso d'uso. Inoltre, il modo giusto per implementare il tuo caso d'uso è - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.