クライアント側のルーティングにreact-routerを使用しています。ボタンがあり、誰かがボタンをクリックしたときに、ユーザーを別のURLにリダイレクトしたいと思います。たとえば、ユーザーを「 http://www.google.com "」にリダイレクトしたい。ナビゲーションミックスインを使用し、this.transitionTo( " https://www.google.com ")を使用しました。しかし、これを行うと、このエラーが発生します。不変の違反:「 https://www.google.com "」という名前のルートが見つかりません。
Window.locationを使用できますが、それは正しい方法ですか?
この回答へのコメントで指摘されているように、これを解決するデフォルトの方法は、目的の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>
);
};
外部リンクに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;
@ 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
同じ問題が発生しましたが、この問題を調査したところ、「ahref」タグを使用するだけでよいことがわかりました。 target = "_ blank"を使用する場合は、リンクを次のように記述してください...
<a href="https://yourLink.com" target="_blank" rel="noopener noreferrer">Your Link</a>