react-router
私は使用することができますLink
ネイティブにルータを反応させることにより、処理されたリンクを作成する要素を。
私は内部的にそれが呼び出すのを見ますthis.context.transitionTo(...)
。
ナビをしたい。リンクからではなく、ドロップダウン選択から(例として)。コードでこれを行うにはどうすればよいですか?なにthis.context
?
Navigation
ミックスインを見ましたが、これなしでできmixins
ますか?
react-router
私は使用することができますLink
ネイティブにルータを反応させることにより、処理されたリンクを作成する要素を。
私は内部的にそれが呼び出すのを見ますthis.context.transitionTo(...)
。
ナビをしたい。リンクからではなく、ドロップダウン選択から(例として)。コードでこれを行うにはどうすればよいですか?なにthis.context
?
Navigation
ミックスインを見ましたが、これなしでできmixins
ますか?
回答:
React Router v5.1.0とフック
useHistory
React> 16.8.0と機能コンポーネントを使用している場合、React Router> 5.1.0に新しいフックがあります。
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
React Router v4
React Routerのv4では、コンポーネント内でプログラムによるルーティングを行うために使用できる3つのアプローチがあります。
withRouter
高次成分を使用してください。<Route>
context
ます。React Routerは、主にhistory
ライブラリのラッパーです。ブラウザとハッシュ履歴を使用して、ブラウザとhistory
のやり取りを処理window.history
します。また、グローバル履歴がない環境で役立つメモリ履歴も提供します。これは、モバイルアプリ開発(react-native
)およびNodeを使用したユニットテストでます。
history
インスタンスがナビゲートするための2つのメソッドがありますpush
とreplace
。history
を訪問済みの場所の配列と考える場合、は配列にpush
新しい場所を追加し、配列replace
内の現在の場所を新しい場所に置き換えます。通常は、push
は、ナビゲートしているときにメソッドます。
ルータに反応の以前のバージョンでは、あなた自身の作成しなければならなかったhistory
インスタンスを、しかし、V4で<BrowserRouter>
、<HashRouter>
、および<MemoryRouter>
コンポーネントは、あなたのためのブラウザ、ハッシュ、およびメモリインスタンスを作成します。React Routerは、ルーターにhistory
関連付けられたインスタンスのプロパティとメソッドを、router
オブジェクトの下のコンテキストから利用できるようにします。
withRouter
高次コンポーネントを使用するwithRouter
高次成分が注入するhistory
成分の小道具としてオブジェクト。これにより、に対処することなく、push
およびreplace
メソッドにアクセスできますcontext
。
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
<Route>
この<Route>
コンポーネントは、場所を一致させるためだけのものではありません。パスレスルートをレンダリングすると、常に現在の場所と一致します。<Route>
コンポーネントは、同じ小道具を渡すwithRouter
あなたがアクセスできるようになるので、history
通過方法をhistory
小道具。
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
しかし、おそらくすべきではない
最後のオプションは、Reactのコンテキストモデルの操作に慣れている場合にのみ使用するオプションです(ReactのContext APIはv16で安定しています)。
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1と2は実装するのが最も簡単な選択肢であるため、ほとんどのユースケースでは、これらが最善の策です。
withRouter
代わりに使用できhistory
ますか?私はもっとドキュメントを読むためにもっと時間を費やす必要があります...
history.push('/new-location')
その動作をボタンや他のDOM要素に関連付けずに実行するにはどうすればよいですか?
Unexpected use of 'history' no-restricted-globals
context
反応16
React-Router 5.1.0+ Answer(フックとReact> 16.8を使用)
useHistory
機能コンポーネントの新しいフックを使用して、プログラムでナビゲートできます。
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+回答
4.0以降では、履歴をコンポーネントの小道具として使用します。
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
注:this.props.historyは、コンポーネントがによってレンダリングされなかった場合には存在しません<Route>
。<Route path="..." component={YourComponent}/>
YourComponentにthis.props.historyを含めるために使用する必要があります
React-Router 3.0.0+回答
3.0以降では、ルーターをコンポーネントのプロップとして使用します。
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0以降回答
2.4以降では、より高次のコンポーネントを使用して、ルーターをコンポーネントの支柱として取得します。
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0以降回答
このバージョンは1.xと下位互換性があるため、アップグレードガイドは必要ありません。例を実行するだけで十分です。
つまり、新しいパターンに切り替えたい場合は、ルーター内にbrowserHistoryモジュールがあり、これを使用してアクセスできます。
import { browserHistory } from 'react-router'
これでブラウザの履歴にアクセスできるようになり、プッシュ、置換などを実行できるようになりました。
browserHistory.push('/some/path')
React-Router 1.xx回答
アップグレードの詳細には触れません。あなたはそれについて読むことができますアップグレードガイドで
ここでの質問に関する主な変更は、ナビゲーションミックスインから履歴への変更です。これで、ブラウザのhistoryAPIを使用してルートを変更しているので、pushState()
します。
Mixinを使用した例を次に示します。
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
これHistory
はラケット/歴史から来ていることに注意してくださいプロジェクト。React-Router自体からではありません。
何らかの理由で(おそらくES6クラスが原因で)Mixinを使用したくない場合は、からルーターから取得した履歴にアクセスできますthis.props.history
。ルーターによってレンダリングされたコンポーネントからのみアクセスできます。したがって、子コンポーネントで使用したい場合は、属性として次のように渡す必要があります。props
。
あなたは彼らの新しいリリースについてもっと読むことができます 1.0.xのドキュメントを
ここは 、コンポーネントの外への移動に関するヘルプページです。
参照history = createHistory()
を取得replaceState
して呼び出すことをお勧めします。
React-Router 0.13.xの回答
私は同じ問題に遭遇し、react-routerに付属するNavigationミックスインでのみ解決策を見つけることができました。
これが私がやった方法です
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
transitionTo()
アクセスせずに電話できた.context
または、豪華なES6を試すこともできます class
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
注:あなたがReduxのを使用している場合、と呼ばれる別のプロジェクトがあり ReactRouter-Reduxのあなたは多少同じアプローチ使用して、ReactRouterのバインディングをReduxの与え リアクト- Reduxのはありませんが
React-Router-Reduxには、アクション作成者から簡単にナビゲートできるいくつかの方法があります。これらは、React Nativeに既存のアーキテクチャーを持っている人にとって特に有用であり、ボイラープレートのオーバーヘッドを最小限に抑えながら、React Webで同じパターンを利用したいと考えています。
次の方法を調べてください。
push(location)
replace(location)
go(number)
goBack()
goForward()
Redux-Thunkでの使用例は次のとおりです。
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
v2.4.0
が、上記のアプローチは、私のために仕事をしません、私のアプリは、すべてのコンソール出力でレンダリングされません。Uncaught TypeError: (0 , _reactRouter.withRouter) is not a function
ここに私のSOの記事へのリンクがあります:stackoverflow.com/questions/37306166/...
2.6.0
。
3.0.x
ですか?多くの人がこのcontext
方法を使用しているようです。
this.props.history
は、コンポーネントがによってレンダリングされなかった場合には存在しません<Route>
。に使用<Route path="..." component={YourComponent}/>
する必要this.props.history
がありYourComponent
ます。
React-Router v2
最新のリリース(v2.0.0-rc5
)では、推奨されるナビゲーション方法は、履歴シングルトンを直接プッシュすることです。コンポーネントドキュメントの外部でのナビゲーションで実際に動作していることがわかります。
関連抜粋:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
新しいreact-router APIを使用している場合は、コンポーネント内のhistory
from を使用する必要がありますthis.props
。
this.props.history.push('/some/path');
それも提供していますpushState
が、ログに記録された警告ごとに非推奨です。
を使用する場合react-router-redux
は、push
次のようにディスパッチできる関数を提供します。
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
ただし、これは、実際にページに移動するためではなく、URLを変更するためにのみ使用できます。
import { browserHistory } from './react-router'
履歴を作成することを忘れないでくださいimport createBrowserHistory from 'history/lib/createBrowserHistory'
。後で、あなたがアクセスすることができますhistory
:コンポーネントの小道具からthis.props.history('/some/path')
var browserHistory = require('react-router').browserHistory; browserHistory.goBack();
push
はURLのみを変更し、実際にはページを変更しません。両方を行うには、browserHistory
からインポートしreact-router
て使用しますbrowserHistory.push('/my-cool-path')
。残念ながら、これは簡単に見つけることはできません。github.com/reactjs/react-router/blob/master/docs/guides/...
ここでは、あなたがこれを行う方法ですreact-router v2.0.0
とES6。react-router
ミックスインから移動しました。
import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
history
、@ Bobbyが述べているシングルトンを使用することだと思います。使用することはできますcontext.router
が、これらのコンポーネントの単体テストを行うと、コンテキスト内でこれだけがインスタンス化されないため、これらのコンポーネントを単体テストすることが非常に困難になります。
React-Router 4.x回答:
私の側では、外部コンポーネントでも実行できる単一の履歴オブジェクトが欲しいです。私がやりたいのは、オンデマンドでインポートする単一のhistory.jsファイルを用意し、それを操作することです。
BrowserRouter
ルーターに変更して、履歴プロップを指定するだけです。これは、必要に応じて操作できる独自の履歴オブジェクトがあること以外は何も変更しません。
が使用するライブラリであるhistoryをインストールする必要がありreact-router
ます。
使用例、ES6表記:
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
BasicComponent.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
2018年4月16日編集:
実際にレンダリングされたコンポーネントから移動する必要がある場合 Route
コンポーネント、次のようにプロップから履歴にアクセスすることもできます。
BasicComponent.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}
this.props.history
ことをお勧めしますが、コンポーネントではないクラスや、Reactコンポーネントとして構築されていないその他のツールで、このようなことを行うのに役立つ解決策はまだ見つけていません小道具を渡すことができます。ご意見ありがとうございます:)
これについては、サーバー側を制御していないため、ハッシュルーターv2を使用しています。
履歴を別のファイル(app_history.js ES6など)に配置します。
import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;
そしてどこでもそれを使用してください!
react-router(app.js ES6)のエントリーポイント:
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
<Router history={appHistory}>
...
</Router>
), document.querySelector('[data-role="app"]'));
コンポーネント内のナビゲーション(ES6):
import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
if (err) {
console.error(err); // login failed
} else {
// logged in
appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
}
})
history
、どちらのアプローチを使用することをお
React Router V4
tl:dr;
if (navigate) {
return <Redirect to="/" push={true} />
}
シンプルで宣言的な答えは、以下と<Redirect to={URL} push={boolean} />
組み合わせて使用する必要があるということです。setState()
push:boolean- trueの場合、リダイレクトすると、現在のエントリを置き換えるのではなく、新しいエントリが履歴にプッシュされます。
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
PS。この例では、ES7 +プロパティ初期化子を使用して状態を初期化しています。興味があればこちらもご覧ください。
withRouter
リロードされているルートにすでにいるときは使用できませんでした。私たちのケースでは、すでにルート上にある場合、または他の場所から選択的に実行する必要がありますsetState
(原因return <Redirect>
)history.push()
。
警告:この回答は1.0より前のReactRouterバージョンのみを対象としています
私はこの回答を1.0.0-rc1のユースケースで更新します!
ミックスインがなくてもこれを行うことができます。
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
コンテキストの問題はcontextTypes
、クラスでを定義しない限りアクセスできないことです。
コンテキストとは、親から子に渡されるのはプロップのようなオブジェクトですが、毎回プロップを再宣言する必要なく、暗黙的に渡されます。https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.htmlを参照してください
何かがうまくいく前に、私はこれを少なくとも10通りの方法で試しました!
@Felipe SkinnerのwithRouter
答えは私にとって少し圧倒的でした、そして、私が新しい "ExportedWithRouter"クラス名を作りたいと思っていませんでした。
これは、現在のReact-Router 3.0.0とES6で最も簡単でクリーンな方法です。
ES6を搭載したReact-Router 3.xx:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
export default withRouter(Example);
または、それがデフォルトのクラスでない場合は、次のようにエクスポートします。
withRouter(Example);
export { Example };
3.xxでは、<Link>
コンポーネント自体がを使用router.push
しているため<Link to=
、次のように、タグを渡すものであれば何でも渡すことができます。
this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
200 OK
、30x
コードの代わりに応答します。この問題を解決するにはどうすればよいですか?
プログラムでナビゲーションを行うには、新しい履歴をのprops.historyにプッシュする必要がありますcomponent
。これにより、次のようなことが機能します。
//using ES6
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
e.preventDefault()
/* Look at here, you can add it here */
this.props.history.push('/redirected');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Redirect!!!
</button>
</div>
)
}
}
export default App;
ES6 + Reactコンポーネントの場合、次のソリューションがうまくいきました。
私はFelippeスキナーをフォローしましたが、私のような初心者を助けるためにエンドツーエンドのソリューションを追加しました。
以下は私が使用したバージョンです:
「react-router」:「^ 2.7.0」
"反応する": "^ 15.3.1"
以下は、react-routerを使用したプログラムによるナビゲーションを使用した私のreactコンポーネントです。
import React from 'react';
class loginComp extends React.Component {
constructor( context) {
super(context);
this.state = {
uname: '',
pwd: ''
};
}
redirectToMainPage(){
this.context.router.replace('/home');
}
render(){
return <div>
// skipping html code
<button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
</div>;
}
};
loginComp.contextTypes = {
router: React.PropTypes.object.isRequired
}
module.exports = loginComp;
以下は私のルーターの設定です:
import { Router, Route, IndexRedirect, browserHistory } from 'react-router'
render(<Router history={browserHistory}>
<Route path='/' component={ParentComp}>
<IndexRedirect to = "/login"/>
<Route path='/login' component={LoginComp}/>
<Route path='/home' component={HomeComp}/>
<Route path='/repair' component={RepairJobComp} />
<Route path='/service' component={ServiceJobComp} />
</Route>
</Router>, document.getElementById('root'));
最善の方法とは言えないかもしれませんが... react-router v4を使用すると、次のTypescriptはいくつかのアイデアを与える可能性があります。
以下のレンダリングされたコンポーネントでは、たとえばLoginPage
、router
オブジェクトはアクセス可能でありrouter.transitionTo('/homepage')
、ナビゲートするために呼び出すだけです。
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
interface MatchWithPropsInterface {
component: typeof React.Component,
router: Router,
history: History,
exactly?: any,
pattern: string
}
class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
render() {
return(
<Match {...this.props} render={(matchProps) => (
React.createElement(this.props.component, this.props)
)}
/>
)
}
}
ReactDOM.render(
<Router>
{({ router }) => (
<div>
<MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
<Miss component={NotFoundView} />
</div>
)}
</Router>,
document.getElementById('app')
);
でリアクト・ルータV4とES6
あなたは使用することができるwithRouter
とthis.props.history.push
。
import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {
this.props.history.push('/redirect-to');
}
}
export default withRouter(Home);
withRouter
クラスベースのコンポーネントで使用するには、以下のようなものを試してください。使用するエクスポートステートメントを変更することを忘れないでください。withRouter
。
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
ホセ・アントニオ・ポスティゴとベン・ウィーラーからの以前の答えに基づいてい
ますか?Typescriptで記述し
、デコレータ
または静的プロパティ/フィールドを使用する
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
今日どんなnpmがインストールされていても。"react-router": "^ 3.0.0"および
"@ types / react-router": "^ 2.0.41"
地平線上のReact-Router v4で、これを行う新しい方法が今あります。
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
react-legoは、react-routerの使用/更新方法を示すサンプルアプリであり、アプリをナビゲートするサンプル機能テストが含まれています。
反応ルータv4で。この2つの方法に従って、プログラムでルーティングします。
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
二番
履歴スタックの現在のエントリを置き換えます
小道具の履歴を取得するには、コンポーネントをラップする必要がある場合があります
ハッシュまたはブラウザの履歴を使用している場合は、次のことができます
hashHistory.push('/login');
browserHistory.push('/login');
hashHistory.push
、未定義のプロパティ「プッシュ」を読み取ることができません。これらはどこからインポートしますか?
現在のReactバージョン(15.3)this.props.history.push('/location');
では問題なく動作しましたが、次の警告が表示されました。
browser.js:49警告:[react-router]
props.history
およびcontext.history
非推奨。使用してくださいcontext.router
。
そして私はcontext.router
このようにしてそれを解決しました:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.backPressed = this.backPressed.bind(this);
}
backPressed() {
this.context.router.push('/back-location');
}
...
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default MyComponent;
これをreact-router v4に実装する際に問題に直面している人。
以下は、rexアクションから反応アプリをナビゲートするための実用的なソリューションです。
history.js
import createHistory from 'history/createBrowserHistory'
export default createHistory()
App.js / Route.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
another_file.jsまたはreduxファイル
import history from './history'
history.push('/test') // this should change the url and re-render Test component
このコメントのおかげで: ReactTrainingの問題のコメント
react-router-reduxを使用してRR4 w / reduxをペアリングする場合は、ルーティングアクションの作成者を使用することreact-router-redux
もオプションです。
import { push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
redux thunk / sagaを使用して非同期フローを管理する場合は、上記のアクションクリエーターをreduxアクションにインポートし、mapDispatchToPropsを使用してコンポーネントを反応させるフックの方が良い場合があります。
react-router-redux
長い間非推奨/アーカイブされています
useHistory
ステートレスコンポーネントでフックを使用することもできます。ドキュメントの例。
import { useHistory } from "react-router"
function HomeButton() {
const history = useHistory()
return (
<button type="button" onClick={() => history.push("/home")}>
Go home
</button>
)
}
注:フックが追加され
react-router@5.1.0
、必要ですreact@>=16.8
正解は執筆時の私にとってのものでした
this.context.router.history.push('/');
ただし、コンポーネントにPropTypeを追加する必要があります
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
PropTypesをインポートすることを忘れないでください
import PropTypes from 'prop-types';
多分最善の解決策ではないかもしれませんが、それは仕事を成し遂げます:
import { Link } from 'react-router-dom';
// create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
基本的に、1つのアクション(この場合はポストの削除)に関連付けられたロジックは、リダイレクトのトリガーを呼び出すことになります。DOMノード「トリガー」をマークアップに追加して、必要なときに便利に呼び出せるようにするため、これは理想的ではありません。また、Reactコンポーネントでは望ましくない可能性があるDOMを直接操作します。
それでも、このタイプのリダイレクトはそれほど頻繁には必要ありません。したがって、コンポーネントマークアップに1つまたは2つの追加の非表示リンクがあっても、特に意味のある名前を付ければ、それほど害はありません。
これは私にとってはうまくいきました、特別なインポートは必要ありません:
<input
type="button"
name="back"
id="back"
class="btn btn-primary"
value="Back"
onClick={() => { this.props.history.goBack() }}
/>
history
追加されたわけではありませんprops
。これは、使用するためにインポートする必要があるHoCに由来します(によって直接送信されるコンポーネントはRoute
、そのHoCによって自動的にラップされますが、インポートが必要ですRoute
...)
代わりにhookrouterを使用してください。react-routerの最新の代替手段です。
https://www.npmjs.com/package/hookrouter
import { useRoutes, usePath, A} from "hookrouter";
選択ボックスを介したリンクに関するOPの質問に答えるには、次のようにします。
navigate('/about');
React Router v4 +の場合
(<Redirect>
コンポーネントを使用できる)最初のレンダリング自体の間に移動する必要がないと想定すると、これがアプリで行っていることです。
nullを返す空のルートを定義します。これにより、履歴オブジェクトにアクセスできます。あなたはあなたのトップレベルでこれを行う必要がありますRouter
が定義さ。
今、あなたは上で行うことができるすべてのことを行うことができます歴史のようにhistory.push()
、history.replace()
、history.go(-1)
などを!
import React from 'react';
import { HashRouter, Route } from 'react-router-dom';
let routeHistory = null;
export function navigateTo(path) {
if(routeHistory !== null) {
routeHistory.push(path);
}
}
export default function App(props) {
return (
<HashRouter hashType="noslash">
<Route
render={({ history }) => {
routeHistory = history;
return null;
}}
/>
{/* Rest of the App */}
</HashRouter>
);
}
react-router-dom:5.1.2
このサイトには3つのページがあり、そのすべてがブラウザーで動的にレンダリングされます。
ページが更新されることはありませんが、サイト内を移動するときに、React RouterがURLを最新に保つ方法に注意してください。これにより、ブラウザの履歴が保持され、戻るボタンやブックマークなどが適切に機能するようになります
スイッチは、そのすべての子要素を検索し、そのパス現在のURLと一致する最初の1をレンダリングします。複数のルートがあるときにいつでも使用できますが、一度にレンダリングするのはそのうちの1つだけです。
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
</div>
</Router>
);
}
// You can think of these components as "pages"
// in your app.
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
function About() {
return (
<div>
<h2>About</h2>
</div>
);
}
function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
</div>
);
}```
したがって、私の答えでは、プログラムでルートにリダイレクトする3つの異なる方法があります。一部のソリューションはすでに提示されていますが、次のソリューションは、追加のデモアプリケーションを備えた機能コンポーネントにのみ焦点を当てています。
次のバージョンを使用します。
反応:16.13.1
反応-dom:16.13.1
react-router:5.2.0
react-router-dom:5.2.0
typescript:3.7.2
構成:
したがって、最初のソリューションはを使用してHashRouter
おり、次のように構成されています。
<HashRouter>
// ... buttons for redirect
<Switch>
<Route exact path="/(|home)" children={Home} />
<Route exact path="/usehistory" children={UseHistoryResult} />
<Route exact path="/withrouter" children={WithRouterResult} />
<Route exact path="/redirectpush" children={RedirectPushResult} />
<Route children={Home} />
</Switch>
</HashRouter>
についてのドキュメントから<HashRouter>
:
A
<Router>
URL(すなわちのハッシュ部分を使用してwindow.location.hash
URLと同期して、あなたのUIを維持します)。
ソリューション:
<Redirect>
してプッシュするuseState
:リダイレクトの処理にRedirectPushAction
使用できる機能コンポーネント(私のリポジトリのコンポーネント)で使用useState
します。トリッキーな部分は、リダイレクトが発生したら、redirect
状態をに戻す必要があることですfalse
。遅延して使用setTimeOut
することで0
、Reactがコミットするまで待機していますRedirect
DOMにするし、次に使用するためにボタンを取得します。
以下の私の例を見つけてください:
const [redirect, setRedirect] = useState(false);
const handleRedirect = useCallback(() => {
let render = null;
if (redirect) {
render = <Redirect to="/redirectpush" push={true} />
// in order wait until commiting to the DOM
// and get back the button for clicking next time
setTimeout(() => setRedirect(false), 0);
}
return render;
}, [redirect]);
return <>
{handleRedirect()}
<button onClick={() => setRedirect(true)}>
Redirect push
</button>
</>
<Redirect>
ドキュメントから:
をレンダリングする
<Redirect>
と、新しい場所に移動します。新しい場所は、サーバー側のリダイレクト(HTTP 3xx)と同様に、履歴スタックの現在の場所をオーバーライドします。
useHistory
フックを使用:私のソリューションにはUseHistoryAction
、以下を表すと呼ばれるコンポーネントがあります:
let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>
useHistory redirect
</button>
useHistory
フックは私たちに私たちのプログラムで移動したり、変更ルートを助け履歴オブジェクトへのアクセスを提供します。
withRouter
して、history
から取得しprops
ます。と呼ばれる1つのコンポーネントを作成しWithRouterAction
、以下のように表示します。
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
withRouter
ドキュメントから読む:
高次コンポーネントを介して、
history
オブジェクトのプロパティと最も近い<Route>
の一致にアクセスできwithRouter
ます。withRouter
更新渡しますmatch
、location
と、history
それがレンダリングするたび包まコンポーネントに小道具。
デモ:
より適切に表現するために、これらの例を使用してGitHubリポジトリを構築しました。以下で見つけてください。
https://github.com/norbitrial/react-router-programmatically-redirect-examples
これが役に立てば幸いです!