web-dev-qa-db-ja.com

react-routerは別のドメインURLにリダイレクトします

クライアント側のルーティングにreact-routerを使用しています。ボタンがあり、誰かがボタンをクリックしたときに、ユーザーを別のURLにリダイレクトしたいと思います。たとえば、ユーザーを「 http://www.google.com "」にリダイレクトしたい。ナビゲーションミックスインを使用し、this.transitionTo( " https://www.google.com ")を使用しました。しかし、これを行うと、このエラーが発生します。不変の違反:「 https://www.google.com "」という名前のルートが見つかりません。

Window.locationを使用できますが、それは正しい方法ですか?

6
sanjeev

この回答へのコメントで指摘されているように、これを解決するデフォルトの方法は、目的のURLを指すa属性を持つアンカー要素(hrefタグ)を使用することです。ユーザーをにルーティングします。ボタンの外観はあるが動作またはアンカーがあるボタンは、ほとんどWebアンチパターンです。この回答の詳細を参照してください: https://stackoverflow.com/a/1667512/1460905

そうは言っても、Webアプリが何らかのアクションを実行してから、ユーザーをリダイレクトする必要がある場合には、確かに潜在的なシナリオがあります。この場合、ユーザーが実行する主なアクションがデータの送信または実際のアクションの実行であり、リダイレクトがより副作用である場合、元の質問は有効です。

この場合、locationオブジェクトのwindowプロパティを使用してみませんか?それは外部の場所に行くための素晴らしい機能的な方法さえ提供します。 ref を参照してください。

したがって、コンポーネントがある場合は、

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

次に、コンポーネントが次のようになるhandleClickを追加します

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

windowはグローバルであるため、インポートする必要はありません。最新のブラウザで完全に機能するはずです。

また、関数として宣言されているコンポーネントがある場合は、 エフェクトフック を使用して、状態が変化したときに場所を変更できます。

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

外部リンクにreact-routerは必要ありません。通常のリンク要素(JSX <a href="..."/>など)を問題なく使用できます。

react-routerが必要なのは、内部ナビゲーション(つまり、コンポーネントからコンポーネントへ)があり、ブラウザのURLバーでアプリが実際に「実際の」URLを切り替えているように見える場合のみです。

Reactルーターを使用してこれを行う簡単な方法を見つけることができませんでした。@ Mikeが書いたように、ユーザーを外部サイトに送信するときはアンカー(<a>タグ)を使用する必要があります。

カスタム<Link>コンポーネントを作成して、React-Router <Link>タグと通常の<a>タグのどちらをレンダリングするかを動的に決定しました。

import * as React from "react";
import {Link, LinkProps} from "react-router-dom";

const ReloadableLink = (props: LinkProps & { forceReload?: boolean }) => {
    const {forceReload, ...linkProps} = props;
    if (forceReload)
        return <a {...linkProps} href={String(props.to)}/>;
    else
        return <Link {...linkProps}>
            {props.children}
        </Link>
};

export default ReloadableLink;
0
gamliela

@ Mike'Pomax 'Kamermansが指摘しているように、外部リンクに移動するために使用できます。

私は通常この方法でそれを行います is-internal-link

import React from 'react'

import { Link as ReactRouterLink} from 'react-router-dom'
import { isInternalLink } from 'is-internal-link'

const Link = ({ children, to, activeClassName, ...other }) => {
  if (isInternalLink(to)) {
    return (
      <ReactRouterLink to={to} activeClassName={activeClassName} {...other}>
        {children}
      </ReactRouterLink>
    )
  }
  return (
    <a href={to} target="_blank" {...other}>
      {children}
    </a>
  )
}

export default Link

免責事項:私はこれの作者です is-internal-link

0
muhajirframe

同じ問題が発生しましたが、この問題を調査したところ、「ahref」タグを使用するだけでよいことがわかりました。 target = "_ blank"を使用する場合は、リンクを次のように記述してください...

<a href="https://yourLink.com" target="_blank" rel="noopener noreferrer">Your Link</a>
0
Bryan Spearman