Lien externe React-Router

114

Puisque j'utilise react-router pour gérer mes itinéraires dans une application react, je suis curieux de savoir s'il existe un moyen de rediriger vers une ressource externe.

Dites que quelqu'un frappe:

example.com/privacy-policy

Je voudrais qu'il redirige vers:

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

Je ne trouve aucune aide pour éviter de l'écrire en JS brut à mon index.html en chargeant avec quelque chose comme:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}
Eric Hodonsky
la source
Quel routeur React utilisez-vous?
Tyler McGinnis
J'utilise la version 3.x
Eric Hodonsky
1
Changez simplement window.location.hrefpour avoir une redirection formelle.
Amirhossein Mehrvarzi
2
@AmirhosseinMehrvarzi cela ne veut rien dire. Pourriez-vous être plus précis ou donner un exemple? De plus, je ne suis pas sûr que vous ayez remarqué, mais cette question a déjà une réponse acceptée concernant React & React Router, qui était le sujet de la question.
Eric Hodonsky
1
@Relic Vous devez l'utiliser comme URL dans votre condition if. J'ai eu un problème similaire il y a quelques jours et j'ai trouvé ce moyen simple et efficace. Il redirige immédiatement. La réponse acceptée est une solution de routage (bien qu'elle enfreigne les principes de la route, étant donné que l'architecture de la route est pour la navigation à l'intérieur de l'application et non pour l'extérieur) qui ne fonctionne pour aucun environnement comme le mien
Amirhossein Mehrvarzi

Réponses:

170

Voici une ligne unique pour utiliser React Router pour rediriger vers un lien externe:

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

Il utilise le concept de composant pur React pour réduire le code du composant à une seule fonction qui, au lieu de rendre quoi que ce soit, redirige le navigateur vers une URL externe.

Fonctionne à la fois sur React Router 3 et 4.

Evgeny Lukianchikov
la source
2
Cela fonctionne mais je cherchais une solution évolutive plus élégante. Voyez ce que j'ai trouvé car cela m'a permis d'aller encore plus loin avec des redirections pour MobileApps, etc. (pas des applications ReactNative, vraiment natives). Maintenant, ce que je fais n'est pas la bonne façon de résoudre mon problème, mais pour résoudre ce problème, je vous suggère d'étudier ma solution également si pour rien d'autre qu'une perspective différente.
Eric Hodonsky
1
Ce n'est pas vraiment si clair dans mon esprit. Je préfère utiliser honnêtement une balise d'ancrage. Deuxièmement, appuyer sur le bouton de retour du navigateur vous renvoie l'itinéraire qui redirige ensuite vers example.zendesk.com/hc/en-us/articles/...
Jonathan Rys
11
Pour un meilleur comportement du bouton Retour (vérifiez pour votre application), utilisez window.location.replace (' example.com' )
MattC
1
Aucune des réponses ne le fait, le message d'origine posait uniquement des questions sur les redirections de clients, tout en sachant qu'il n'y a pas de prise en charge de la vraie redirection de type 301 ou 302.
Eric Hodonsky
51

Il n'est pas nécessaire d'utiliser le <Link />composant de react-router.

Si vous souhaitez accéder au lien externe, utilisez une balise d'ancrage.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
Diego Laciar
la source
20
L'OP demandait comment le faire par programme, et non par déclaration
Eric Hodonsky
13
Réponse sans rapport et trompeuse.
Priya Ranjan Singh
1
Si vous l'utilisez, ajoutez rel="noopener noreferrer"au<a>
S ..
5
Bonne réponse, tout le monde ne s'en souciera pas tant qu'il le fera fonctionner.
FrankByte.com
39

J'ai fini par construire mon propre composant. <Redirect> Il prend des informations sur l' react-routerélément pour que je puisse les conserver dans mes itinéraires. Tel que:

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

Voici mon composant au cas où tout le monde est curieux:

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 - NOTE: C'est avec react-router: 3.0.5, ce n'est pas si simple en 4.x

Eric Hodonsky
la source
vous n'avez rien à faire, réagir est un framework, et il y a beaucoup de valeur dans un framework. CECI est comment le faire dans le cadre de réaction. Cependant, il ne prend PAS en compte le module d'historique du navigateur qui pourrait être inclus ici, ce qui le rend encore plus utile. Veuillez également noter que "window.location" est comme cela a été fait en 1999. C'est juste une façon de l'ajouter à votre table de routes pour le routage côté client. Ce n'est pas une «bonne» solution.
Eric Hodonsky
dans react -router v4, vous pouvez utiliser le composant de rendu à la place
Irrech
3
@Irrech "rendre le composant à la place" ne signifie rien. Si vous avez une réponse à la question, veuillez l'ajouter et donner des détails sur la manière dont vous la mettriez en œuvre.
Eric Hodonsky
3
@MuhammadUmer ou vous utilisez simplement une balise d'ancrage. react-router est strictement destiné au routage uniquement dans votre application. vous pouvez être en désaccord avec cette décision de conception (je sais que je le fais), mais ce n'est pas "mieux fait en 1999", c'est juste la même chose.
worc
21

Il n'a pas besoin de demander le routeur de réaction. Cette action peut être effectuée de manière native et est fournie par le navigateur.

juste utiliser window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}
Alan
la source
1
Cette réponse est incomplète, ne permet pas d'abstraction ou sa relation avec le routeur
Eric Hodonsky
8
Tel est le but. Il n'a pas besoin de demander le routeur de réaction. Cette action peut être effectuée de manière native et est fournie par le navigateur.
Alan
10

Avec le composant Link de react-router, vous pouvez le faire. Dans le prop " to ", vous pouvez spécifier 3 types de données:

  • une chaîne : une représentation sous forme de chaîne de l'emplacement du lien, créée en concaténant le chemin d'accès, la recherche et les propriétés de hachage de l'emplacement.
  • un objet : un objet qui peut avoir l'une des propriétés suivantes:
    • chemin d'accès : une chaîne représentant le chemin vers lequel établir un lien.
    • recherche : représentation sous forme de chaîne des paramètres de requête.
    • hash : un hachage à mettre dans l'URL, par exemple # a-hash.
    • état : état à conserver à l'emplacement.
  • une fonction : une fonction à laquelle l'emplacement actuel est passé comme argument et qui doit renvoyer une représentation de l'emplacement sous forme de chaîne ou d'objet

Pour votre exemple (lien externe):

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

Vous pouvez faire ce qui suit:

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

Vous pouvez également transmettre les accessoires que vous souhaitez utiliser, tels qu'un titre, un identifiant, un nom de classe, etc.

Víctor Daniel
la source
1
C'est la solution la plus simple et fonctionne bien.
hPNJ7MHTyg
5

En utilisant certaines des informations ici, j'ai trouvé le composant suivant que vous pouvez utiliser dans vos déclarations d'itinéraire. Il est compatible avec React Router v4.

Il utilise du typographie, mais devrait être assez simple pour convertir en javascript natif:

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

Et utiliser avec:

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

J'ai eu de la chance avec ceci:

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

Je ne pense pas que React-Router offre ce support. La documentation mentionne

Une <Redirection> configure une redirection vers une autre route dans votre application pour conserver les anciennes URL.

Vous pouvez essayer d'utiliser quelque chose comme React-Redirect à la place

ytibrewala
la source
1

Pour développer la réponse d'Alan, vous pouvez créer un <Route/>qui redirige tous <Link/>les attributs «vers» contenant «http:» ou «https:» vers la bonne ressource externe.

Vous trouverez ci-dessous un exemple de travail qui peut être placé directement dans votre <Router>.

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

POUR V3, bien que cela puisse fonctionner pour V4. En partant de la réponse d'Eric, j'avais besoin de faire un peu plus, comme gérer le développement local où «http» n'est pas présent sur l'url. Je redirige également vers une autre application sur le même serveur.

Ajouté au fichier du routeur:

import RedirectOnServer from './components/RedirectOnServer';

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

Et le composant:

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
la source
-1

En utilisant React avec Typescript, vous obtenez une erreur car la fonction doit renvoyer un élément react, pas void. Je l'ai donc fait de cette façon en utilisant la méthode de rendu Route (et en utilisant le routeur React v4):

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

Où vous pouvez utiliser à la place window.location.assign(), window.location.replace()etc.

chezwhite
la source
-2

Si vous utilisez le rendu côté serveur, vous pouvez utiliser StaticRouter. Avec votre composant au contextfur propset à mesure , puis en ajoutant <Redirect path="/somewhere" />dans votre application. L'idée est que chaque fois que react-router correspond à un composant de redirection, il ajoutera quelque chose dans le contexte que vous avez transmis au routeur statique pour vous faire savoir que votre chemin correspond à un composant de redirection. maintenant que vous savez que vous avez frappé une redirection, il vous suffit de vérifier si c'est la redirection que vous recherchez. puis redirigez simplement via le serveur. ctx.redirect('https://example/com').

Rei Dien
la source
Je demande un moyen de le faire chez le client. Cela devrait en fait être fait au niveau DNS si cela est fait correctement. Le deuxième serait dans la demande initiale du serveur. Puisque j'héberge sur S3, il n'y a pas de côté serveur. Donc, je suis bloqué pour le moment jusqu'à ce que notre responsable des dev-ops puisse faire la redirection au niveau du service.
Eric Hodonsky
ce que vous pouvez faire est,<Redirect push={ true } to="/pathtoredirect" />
Rei Dien
-4

J'ai pu réaliser une redirection dans react-router-dom en utilisant ce qui suit

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

Pour mon cas, je cherchais un moyen de rediriger les utilisateurs chaque fois qu'ils visitent l'URL racine http://myapp.comvers un autre endroit dans l'application http://myapp.com/newplace. donc ce qui précède a aidé.

walecloud
la source
2
L'OP indique clairement qu'il essaie de rediriger vers une ressource externe, pas vers une route à l'intérieur de la même application.
Neets
De toute évidence, j'étais précis sur mon cas d'utilisation et je l'ai laissé tomber s'il pouvait l'appliquer au sien. ma solution dit que dans mon application, il pourrait l'utiliser comme exemple.
walecloud
1
Si vous souhaitez présenter votre cas d'utilisation à des personnes, veuillez écrire un blog à ce sujet. Stackoverflow sert à répondre à la requête des utilisateurs, pas à votre cas d'utilisation. De plus, la bonne façon de mettre en œuvre votre cas d'utilisation est - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas