Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-router redirect to a different domain url

I am using react-router for client side routing. I have a button and when some one clicks the button, I want to redirect the user to a different url. For e.g I want to redirect the user to "http://www.google.com". I used navigation mixin and used this.transitionTo("https://www.google.com"). But when I do this I get this error Invariant Violation: Cannot find a route named "https://www.google.com".

I can use window.location but is that the right way to go?

like image 427
sanjeev Avatar asked Jun 28 '15 03:06

sanjeev


People also ask

How do I redirect to another domain in react?

Use the window. location. replace() method to redirect to an external url in React, e.g. window.

How do I change the default URL in react?

Use the Navigate element to set a default route with redirect in React Router, e.g. <Route path="/" element={<Navigate to="/dashboard" />} /> . The Navigate element changes the current location when it is rendered. Copied!


3 Answers

As pointed out in the comments to this answer, default way of solving this would be to use anchor element (the a tag) with href attribute that points at the destination URL that you'd like to route the user to. A button that has appearance of a button but behavior or an anchor is pretty much a web anti-pattern. See more info in this answer: https://stackoverflow.com/a/1667512/1460905.

That said, there certainly is a potential scenario when a web app needs to perform some action and only then redirect the user. In this case, if primary action the user takes is submitting some data or really performing an action, and redirect is more of a side-effect, then the original question is valid.

In this case, why not use location property of window object? It even provides a nice functional method to go to external location. See the ref.

So, if you have a component, say

class Button extends Component {
  render() {
    return (
      <button onClick={this.handleClick.bind(this)} />
    );
  }
}

then add handleClick that would make the component look like

class Button extends Component {
  handleClick() {
    // do something meaningful, Promises, if/else, whatever, and then
    window.location.assign('http://github.com');
  }

  render() {
    return (
      <button onClick={this.handleClick.bind(this)} />
    );
  }
}

No need to import window since it's global. Should work perfectly in any modern browser.

Also, if you have a component that is declared as a function, you may possibly use the effect hook to change location when state changes, like

const Button = () => {
  const [clicked, setClicked] = useState(false);

  useEffect(() => {
    if (clicked) {
      // do something meaningful, Promises, if/else, whatever, and then
      window.location.assign('http://github.com');
    }
  });

  return (
    <button onClick={() => setClicked(true)}></button>
  );
};
like image 151
rishat Avatar answered Oct 09 '22 07:10

rishat


You don't need react-router for external links, you can use regular link elements (i.e. <a href="..."/>) just fine.

You only need react-router when you have internal navigation (i.e. from component to component) for which the browser's URL bar should make it look like your app is actually switching "real" URLs.

Edit because people seem to think you can't use an <a href="..." if you need to "do work first", an example of doing exactly that:

render() {
  return <a href={settings.externalLocation} onClick={evt => this.leave(evt)}/>
}

async leave(evt) {
  if (this.state.finalized) return;

  evt.preventDefault();

  // Do whatever you need to do, but do it quickly, meaning that if you need to do
  // various things, do them all in parallel instead of running them one by one:
  await Promise.all([
    utils.doAllTheMetrics(),
    user.logOutUser(),
    store.cleanUp(),
    somelib.whatever(),
  ]);

  // done, let's leave.
  this.setState({ finalized: true }), () => evt.target.click());
}

And that's it: when you click the link (that you styled to look like a button because that's what CSS is for) React checks if it can safely navigate away as a state check.

  • If it can, it lets that happen.
  • If it can't:
    1. it prevents the navigation of occurring via preventDefault(),
    2. does whatever work it needs to do, and then
    3. marks itself as "it is safe to leave now", then retriggers the link.
like image 37
Mike 'Pomax' Kamermans Avatar answered Oct 09 '22 08:10

Mike 'Pomax' Kamermans


You can try and create a link element and click it from code. This work for me

const navigateUrl = (url) => {

let element = document.createElement('a');

if(url.startsWith('http://') || url.startsWith('https://')){
  element.href =  url;
} else{
  element.href = 'http://' + url;
}

element.click();
}
like image 40
Odeyinka Olubunmi Avatar answered Oct 09 '22 06:10

Odeyinka Olubunmi