Łącze zewnętrzne React-Router


114

Ponieważ używam routera React do obsługi tras w aplikacji Reaguj, jestem ciekaw, czy istnieje sposób na przekierowanie do zasobu zewnętrznego.

Powiedz, że ktoś uderza:

example.com/privacy-policy

Chciałbym przekierować do:

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

Znajduję dokładnie zero pomocy w unikaniu pisania tego w zwykłym JS na moim index.html ładującym się za pomocą czegoś takiego:

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

Którego routera React używasz?
— Tyler McGinnis

Używam wersji 3.x
— Eric Hodonsky

1
Po prostu zmień, window.location.hrefaby mieć formalne przekierowanie.
— Amirhossein Mehrvarzi

2
@AmirhosseinMehrvarzi to właściwie nic nie znaczy. Czy mógłbyś być bardziej szczegółowy lub podać przykład? Nie jestem też pewien, czy zauważyłeś, ale to pytanie ma już zaakceptowaną odpowiedź dotyczącą routera React & React, o co chodzi w tym pytaniu.
— Eric Hodonsky

1
@Relic Musisz użyć tego jako adresu URL w swoim warunku if. Miałem podobny problem kilka dni temu i uznałem ten sposób za prosty i skuteczny. Przekierowuje natychmiast. Zaakceptowaną odpowiedzią jest rozwiązanie routingu (chociaż narusza zasady trasy, biorąc pod uwagę, że architektura trasy służy do nawigacji wewnątrz aplikacji, a nie na zewnątrz), które nie działa w żadnym środowisku takim jak moje
— Amirhossein Mehrvarzi

Odpowiedzi:


170

Oto jedna linijka dotycząca używania React Router do przekierowania do łącza zewnętrznego:

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

Wykorzystuje koncepcję czystego komponentu React, aby zredukować kod komponentu do pojedynczej funkcji, która zamiast renderować cokolwiek, przekierowuje przeglądarkę do zewnętrznego adresu URL.

Działa zarówno na React Router 3, jak i 4.


2
To działa, ale szukałem bardziej eleganckiego, skalowalnego rozwiązania. Zobacz, co wymyśliłem, ponieważ pozwoliło mi to pójść jeszcze dalej z przekierowaniami dla aplikacji mobilnych itp. (Nie ReactNative, prawdziwie natywne aplikacje). To, co robię, nie jest właściwym sposobem rozwiązania mojego problemu, ale sugeruję, abyś zbadał również moje rozwiązanie, choćby z innej perspektywy.
— Eric Hodonsky

1
To naprawdę nie jest takie czyste w mojej głowie. Wolałbym uczciwie użyć tagu kotwicy. Po drugie, naciśnięcie przycisku Wstecz w przeglądarce zwraca trasę, która następnie przekierowuje z powrotem do example.zendesk.com/hc/en-us/articles/ ...
— Jonathan Rys

11
Aby uzyskać lepsze zachowanie przycisku Wstecz (zweryfikuj swoją aplikację), użyj window.location.replace („ example.com” )
— MattC

1
Żadna z odpowiedzi nie odpowiada, oryginalny post pytał tylko o przekierowania klientów, mając świadomość, że nie ma prawdziwej obsługi przekierowań typu 301 lub 302.
— Eric Hodonsky

51

Nie ma potrzeby używania <Link />komponentu z routera reaktywnego.

Jeśli chcesz przejść do linku zewnętrznego, użyj tagu kotwicy.

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

20
OP pytał, jak to zrobić programowo, a nie deklaratywnie
— Eric Hodonsky

13
Niepowiązana i myląca odpowiedź.
— Priya Ranjan Singh

1
Jeśli to zrobisz, dodaj rel="noopener noreferrer"do<a>
— S ..

5
Dobra odpowiedź, nie każdemu będzie to zależało tak długo, jak długo będzie działać.
— FrankByte.com

39

Skończyło się na zbudowaniu własnego komponentu. <Redirect> Pobiera informacje z react-routerelementu, więc mogę je przechowywać w moich trasach. Jak na przykład:

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

Oto mój komponent na wypadek, gdyby ktoś był ciekawy:

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;

EDYCJA - UWAGA: To jest z react-router: 3.0.5, to nie jest takie proste w 4.x


nie MUSISZ nic robić, reagujesz to framework, a framework ma dużą wartość. Tak to się robi w ramach reagowania. NIE bierze jednak pod uwagę modułu historii przeglądarki, który można by zawinąć tutaj, co czyni go jeszcze bardziej użytecznym. Zwróć również uwagę, że "window.location" to sposób, w jaki to było zrobione w 1999 roku. Jest to tylko sposób na dodanie go do tabeli tras dla routingu po stronie klienta. To nie jest „dobre” rozwiązanie.
— Eric Hodonsky

w React -router v4 możesz użyć komponentu renderowania
— Irrech

3
@Irrech „renderuj zamiast komponentu” nic nie znaczy. Jeśli masz odpowiedź na pytanie, dodaj ją i opisz szczegółowo, jak byś ją wdrożył.
— Eric Hodonsky

3
@MuhammadUmer lub po prostu użyj tagu kotwicy. reakcja-router jest dość ściśle przeznaczona do routingu tylko w Twojej aplikacji. można nie zgodzić się z tej decyzji projektowej (wiem, że nie), ale nie jest to „zrobić lepiej w 1999 roku”, to po prostu zrobić to samo.
— worc

21

Nie ma potrzeby żądania odpowiedzi routera. Tę czynność można wykonać natywnie i zapewnia ją przeglądarka.

po prostu użyj window.location

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

1
Ta odpowiedź jest niekompletna, nie pozwala na abstrakcję lub jest powiązana z routerem
— Eric Hodonsky

8
To jest cel. Nie ma potrzeby żądania odpowiedzi routera. Tę czynność można wykonać natywnie i zapewnia ją przeglądarka.
— Alan

10

Z komponentem Link w React-router możesz to zrobić. W właściwości „ do ” możesz określić 3 typy danych:

  • ciąg : ciąg znaków reprezentujący położenie łącza, utworzony przez konkatenację nazwy ścieżki, wyszukiwania i właściwości skrótu lokalizacji.
  • obiekt : obiekt, który może mieć dowolną z następujących właściwości:
    • pathname : ciąg reprezentujący ścieżkę do połączenia.
    • search : ciąg znaków reprezentujący parametry zapytania.
    • hash : hash do umieszczenia w adresie URL, np. # a-hash.
    • stan : stan, aby zachować lokalizację.
  • a function : funkcja, do której bieżące położenie jest przekazywane jako argument i która powinna zwrócić reprezentację położenia w postaci ciągu lub obiektu

Na przykład (link zewnętrzny):

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

Możesz wykonać następujące czynności:

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

Możesz również przekazywać rekwizyty, na których chcesz się znaleźć, takie jak tytuł, identyfikator, nazwa klasy itp.


1
To najprostsze rozwiązanie i działa dobrze.
— hPNJ7MHTyg

5

Korzystając z niektórych informacji tutaj, wymyśliłem następujący komponent, którego możesz użyć w deklaracjach tras. Jest kompatybilny z React Router v4.

Używa maszynopisu, ale konwersja do natywnego javascript powinna być dość prosta:

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

I używaj z:

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

2

Miałem szczęście z tym:

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

1

Myślę, że React-Router nie zapewnia takiej obsługi. Dokumentacja wspomina

<Redirect> ustawia przekierowanie do innej trasy w Twojej aplikacji, aby zachować stare adresy URL.

Można spróbować użyć czegoś podobnego React przekierowanie zamiast


1

Aby rozwinąć odpowiedź Alana, możesz utworzyć <Route/>przekierowanie wszystkich<Link/> z atrybutami „do” zawierającymi „http:” lub „https:” do właściwego zasobu zewnętrznego.

Poniżej znajduje się działający przykład, który można umieścić bezpośrednio w pliku <Router>.

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

0

DLA V3, chociaż może działać dla V4. Wychodząc od odpowiedzi Erica, musiałem zrobić trochę więcej, na przykład zająć się rozwojem lokalnym, gdzie „http” nie występuje w adresie URL. Przekierowuję również do innej aplikacji na tym samym serwerze.

Dodano do pliku routera:

import RedirectOnServer from './components/RedirectOnServer';

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

A komponent:

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

Używając Reacta z Typescript, otrzymujesz błąd, ponieważ funkcja musi zwrócić element reakcji, a nie void. Zrobiłem to w ten sposób, używając metody renderowania trasy (i używając routera React v4):

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

Gdzie można również użyć zamiast window.location.assign(), window.location.replace()etc


-2

Jeśli używasz renderowania po stronie serwera, możesz użyć StaticRouter. Za pomocą swojego contextas, propsa następnie dodając <Redirect path="/somewhere" />komponent do swojej aplikacji. Chodzi o to, że za każdym razem, gdy reakcja-router dopasuje komponent przekierowania, doda coś do kontekstu przekazanego do routera statycznego, aby poinformować cię, że twoja ścieżka pasuje do komponentu przekierowania. teraz, gdy wiesz, że trafiłeś w przekierowanie, wystarczy sprawdzić, czy to przekierowanie, którego szukasz. następnie po prostu przekieruj przez serwer. ctx.redirect('https://example/com').


Proszę o sposób na zrobienie tego w kliencie. W rzeczywistości należy to zrobić na poziomie DNS, jeśli zostanie wykonane poprawnie. Drugi byłby w początkowym żądaniu serwera. Ponieważ hostuję na S3, nie ma po stronie serwera. Więc na razie utknąłem, dopóki nasz facet od deweloperów nie będzie mógł wykonać przekierowania na poziomie usługi.
— Eric Hodonsky

co możesz zrobić,<Redirect push={ true } to="/pathtoredirect" />
— Rei Dien

-4

Udało mi się uzyskać przekierowanie w React-router-dom za pomocą następującego

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

W moim przypadku szukałem sposobu na przekierowanie użytkowników za każdym razem, gdy odwiedzają główny adres URL http://myapp.comdo innego miejsca w aplikacji http://myapp.com/newplace. więc powyższe pomogło.


2
OP wyraźnie stwierdza, że ​​próbuje przekierować do zasobu zewnętrznego, a nie do trasy w tej samej aplikacji.
— Neets,

Najwyraźniej sprecyzowałem mój przypadek użycia i porzuciłem to, gdyby mógł zastosować to do swojego. moje rozwiązanie mówi w mojej aplikacji, mógłby użyć tego jako przykładu.
— walecloud

1
Jeśli chcesz pokazać ludziom swój przypadek użycia, napisz o tym blog. Stackoverflow służy do odpowiadania na zapytania, które mają ludzie, a nie do twojego przypadku użycia. Prawidłowy sposób na zaimplementowanie tego przypadku to - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
— Abhas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.