React-Router Enlace externo

113

Como estoy usando react-router para manejar mis rutas en una aplicación de reacción, tengo curiosidad por saber si hay una forma de redirigir a un recurso externo.

Digamos que alguien golpea:

example.com/privacy-policy

Me gustaría redirigir a:

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

No encuentro exactamente ninguna ayuda para evitar escribirlo en JS simple en mi index.html cargando con algo como:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}
Eric Hodonsky
fuente
¿Qué React Router estás usando?
Tyler McGinnis
Estoy usando la versión 3.x
Eric Hodonsky
1
Simplemente cambie window.location.hrefpara tener una redirección formal.
Amirhossein Mehrvarzi
2
@AmirhosseinMehrvarzi eso en realidad no significa nada. ¿Podría ser más específico o dar un ejemplo? Además, no estoy seguro de si lo has notado, pero esta pregunta ya tiene una respuesta aceptada relacionada con React & React Router, que es de lo que trataba la pregunta.
Eric Hodonsky
1
@Relic Debe usar eso como su URL en su condición if. Tuve un problema similar hace unos días y encontré esta forma simple y efectiva. Redirige inmediatamente. La respuesta aceptada es una solución de enrutamiento (si bien viola los principios de la ruta, considerando que la arquitectura de la ruta es para la navegación dentro de la aplicación, no para el exterior) que no funciona para ningún entorno como el mío
Amirhossein Mehrvarzi

Respuestas:

170

Aquí hay una sola línea para usar React Router para redirigir a un enlace externo:

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

Utiliza el concepto de componente puro de React para reducir el código del componente a una sola función que, en lugar de representar nada, redirige el navegador a una URL externa.

Funciona tanto en React Router 3 como en 4.

Evgeny Lukianchikov
fuente
2
Esto funciona, pero estaba buscando una solución escalable más elegante. Vea lo que se me ocurrió, ya que me permitió ir aún más lejos con redireccionamientos para aplicaciones móviles, etc. (no ReactNative, aplicaciones verdaderamente nativas). Ahora bien, lo que estoy haciendo no es la manera correcta de resolver mi problema, pero para resolver este problema le sugiero que investigue mi solución también, aunque solo sea con una perspectiva diferente.
Eric Hodonsky
1
Esto no es tan claro en mi mente. Prefiero usar una etiqueta de anclaje honestamente. En segundo lugar, presionar el botón Atrás en el navegador le devuelve la ruta que luego redirige a example.zendesk.com/hc/en-us/articles/…
Jonathan Rys
11
Para un mejor comportamiento del botón de retroceso (verifique su aplicación), use window.location.replace (' example.com' )
MattC
1
Ninguna de las respuestas lo hace, la publicación original preguntaba solo sobre redireccionamientos de clientes, MIENTRAS era consciente de que no hay soporte de redireccionamiento verdadero de tipo 301 o 302.
Eric Hodonsky
50

No es necesario utilizar <Link />componentes de react-router.

Si desea ir a un enlace externo, use una etiqueta de anclaje.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
Diego Laciar
fuente
20
El OP preguntaba cómo hacerlo de forma programática, no declarativa
Eric Hodonsky
13
Respuesta no relacionada y engañosa.
Priya Ranjan Singh
1
Si usa esto, agregue rel="noopener noreferrer"al<a>
S ..
5
Buena respuesta, no a todo el mundo le importará mientras lo haga funcionar.
FrankByte.com
39

De hecho, terminé construyendo mi propio Componente. <Redirect> Toma información del react-routerelemento para que pueda mantenerla en mis rutas. Como:

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

Aquí está mi componente en caso de que alguien tenga curiosidad:

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;

EDITAR - NOTA: Esto es con react-router: 3.0.5 , no es tan simple en 4.x

Eric Hodonsky
fuente
no TIENES que hacer nada, reaccionar es un marco, y hay mucho valor en un marco. ESTO es cómo hacerlo dentro del marco de reacción. Sin embargo, NO TIENE en cuenta el módulo del historial del navegador que podría incluirse aquí, lo que hace que esto sea aún más útil. También tenga en cuenta que "window.location" es cómo se hizo en 1999. Esta es solo una forma de agregarlo a su tabla de rutas para el enrutamiento del lado del cliente. No es una "buena" solución.
Eric Hodonsky
en react -router v4 puede usar render en lugar de componente
Irrech
3
@Irrech "render en lugar de componente" no significa nada. Si tiene una respuesta a la pregunta, agréguela y proporcione algunos detalles de cómo la implementaría.
Eric Hodonsky
3
@MuhammadUmer o simplemente usa una etiqueta de anclaje. react-router está diseñado estrictamente para enrutar solo dentro de su aplicación. puede estar en desacuerdo con esa decisión de diseño (sé que lo hacen), pero no es "hecho mejor en 1999", que acaba de hacer lo mismo.
Trabajo
21

No necesita solicitar reaccionar enrutador. Esta acción se puede realizar de forma nativa y la proporciona el navegador.

Solo usa window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}
Alan
fuente
1
Esta respuesta está incompleta, no permite la abstracción o su relación con el enrutador
Eric Hodonsky
8
Ésta es la meta. No necesita solicitar reaccionar enrutador. Esta acción se puede realizar de forma nativa y la proporciona el navegador.
Alan
10

Con el componente Link de react-router puedes hacerlo. En la opción " a " puede especificar 3 tipos de datos:

  • una cadena : una representación de cadena de la ubicación del enlace, creada mediante la concatenación del nombre de ruta, la búsqueda y las propiedades hash de la ubicación.
  • un objeto : un objeto que puede tener cualquiera de las siguientes propiedades:
    • nombre de ruta : una cadena que representa la ruta de acceso.
    • búsqueda : una representación de cadena de parámetros de consulta.
    • hash : un hash para poner en la URL, por ejemplo, # a-hash.
    • estado : estado para persistir en la ubicación.
  • una función : una función a la que se pasa la ubicación actual como argumento y que debe devolver la representación de la ubicación como una cadena o como un objeto

Para su ejemplo (enlace externo):

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

Puede hacer lo siguiente:

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

También puede pasar los accesorios en los que le gustaría estar, como título, identificación, nombre de clase, etc.

Víctor Daniel
fuente
1
Esta es la solución más simple y funciona bien.
hPNJ7MHTyg
5

Usando parte de la información aquí, se me ocurrió el siguiente componente que puede usar dentro de sus declaraciones de ruta. Es compatible con React Router v4.

Está usando mecanografiado, pero debería ser bastante sencillo convertirlo a 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;
      }}
    />
  );
};

Y usar con:

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

Tuve suerte con esto:

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

No creo que React-Router proporcione este soporte. La documentación menciona

Un <Redirect> configura un redireccionamiento a otra ruta en su aplicación para mantener las URL antiguas.

Puede intentar usar algo como React-Redirect en su lugar

ytibrewala
fuente
1

Para ampliar la respuesta de Alan, puede crear un <Route/>que redirija a todos<Link/> los atributos "a" que contengan "http:" o "https:" al recurso externo correcto.

A continuación se muestra un ejemplo funcional de esto que se puede colocar directamente en su archivo <Router>.

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

PARA V3, aunque puede funcionar para V4. Saliendo de la respuesta de Eric, necesitaba hacer un poco más, como manejar el desarrollo local donde 'http' no está presente en la URL. También estoy redirigiendo a otra aplicación en el mismo servidor.

Agregado al archivo del enrutador:

import RedirectOnServer from './components/RedirectOnServer';

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

Y el 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;
MattC
fuente
-1

Al usar React con TypeScript, obtiene un error ya que la función debe devolver un elemento react, no void. Así que lo hice de esta manera usando el método de renderizado de ruta (y usando React router v4):

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

Donde en su lugar también podría usar window.location.assign(), window.location.replace()etc.

chezwhite
fuente
-2

Si está utilizando el desgarro del lado del servidor, puede utilizar StaticRouter. Con su contextas propsy luego agregando <Redirect path="/somewhere" />componente en su aplicación. La idea es que cada vez que react-router coincida con un componente de redireccionamiento, agregará algo en el contexto que pasó al enrutador estático para hacerle saber que su ruta coincide con un componente de redireccionamiento. ahora que sabe que ha accedido a una redirección, solo tiene que comprobar si esa es la redirección que está buscando. luego simplemente redirigir a través del servidor. ctx.redirect('https://example/com').

Rei Dien
fuente
Estoy pidiendo una forma de hacerlo en el cliente. En realidad, debería hacerse a nivel de DNS si se hace correctamente. El segundo sería en la solicitud inicial del servidor. Dado que estoy alojando en S3, no hay servidor. Así que estoy atascado por ahora hasta que nuestro encargado de operaciones de desarrollo pueda realizar la redirección en el nivel de servicio.
Eric Hodonsky
lo que puedes hacer es,<Redirect push={ true } to="/pathtoredirect" />
Rei Dien
-4

Pude lograr una redirección en react-router-dom usando lo siguiente

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

En mi caso, estaba buscando una forma de redirigir a los usuarios cada vez que visitan la URL raíz http://myapp.coma otro lugar dentro de la aplicación http://myapp.com/newplace. así que lo anterior ayudó.

nube de aguas
fuente
2
El OP establece claramente que está tratando de redirigir a un recurso externo, no a una ruta dentro de la misma aplicación.
Neets
Claramente, fui específico sobre mi caso de uso y lo dejé si podía aplicarlo al suyo. mi solución dice que dentro de mi aplicación, podría usar eso como ejemplo.
walecloud
1
Si desea mostrar su caso de uso a las personas, escriba un blog al respecto. Stackoverflow es para responder la consulta que la gente tiene, no su caso de uso. Además, la forma correcta de implementar su caso de uso es - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas