現在のReact Routerのバージョン(v3)では、サーバーからのレスポンスを受け取り、browserHistory.push
を使って適切なレスポンスページに移動することができます。しかし、これはv4では利用できず、これを処理する適切な方法がよくわかりません。
この例では、Reduxを使って、_components/app-product-form.js_は、ユーザーがフォームを送信すると、this.props.addProduct(props)
を呼び出します。サーバーが成功を返すと、ユーザーはCartページに移動します。
// actions/index.js
export function addProduct(props) {
return dispatch =>
axios.post(`${ROOT_URL}/cart`, props, config)
.then(response => {
dispatch({ type: types.AUTH_USER });
localStorage.setItem('token', response.data.token);
browserHistory.push('/cart'); // no longer in React Router V4
});
}
React Router v4の関数からCartページへのリダイレクトを行うにはどうしたらいいですか?
React Router v4はv3(およびそれ以前)とは根本的に異なり、以前のようにbrowserHistory.push()
を行うことはできません。
もっと詳しく知りたい方は This discussion が関連しているようです。
なぜなら、<BrowserRouter>
は、独自のヒストリーインスタンスを作成し、そのヒストリーの変更を監視しているからです。なぜなら、<BrowserRouter>
は独自のヒストリーインスタンスを作成し、その変更をリッスンするからです。
代わりに、これを行うためのいくつかのオプションがあります。
代わりに withRouter
高次コンポーネントを使用して、それを履歴にプッシュするコンポーネントにラップします。例えば、以下のようになります。
<!-- language: lang-js -->
import React from "react";
import { withRouter } from "react-router-dom";
class MyComponent extends React.Component {。
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
詳しくはofficial documentationをご覧ください。
withRouterの高次コンポーネントを介して、history
オブジェクトのプロパティや、最も近い<Route>
'のmatch
にアクセスすることができます。withRouterは、ルートが変更されるたびに、<Route>
のrender props: { match, location, history }
と同じpropsで、コンポーネントを再レンダリングします。
コンテキストを使うことは最も簡単な解決策の一つかもしれませんが、実験的なAPIであるため、不安定でサポートされていません。他の手段が使えない場合にのみ使用してください。以下にその例を示します。
<!-- language: lang-js -->
import React from "react";
import PropTypes from "prop-types";
class MyComponent extends React.Component {
static contextTypes = {
ルータです。PropTypes.object
}
コンストラクタ(props, context) {
スーパー(props, context);
}
...
myFunction() {
this.context.router.history.push("/some/Path");
}
...
}
コンテキストについては、official documentationをご覧ください。
アプリケーションを安定させたいのであれば、contextは使用しないでください。これは実験的なAPIであり、Reactの将来のリリースでは壊れてしまう可能性があります。
これらの警告にもかかわらず、どうしてもコンテキストを使いたい場合は、コンテキストの使用を狭い範囲に限定し、可能な限りコンテキストAPIを直接使用しないようにして、APIが変更されたときに簡単にアップグレードできるようにしてください'。
これが私のやり方です。
import React, {Component} from 'react';
export default class Link extends Component {
constructor(props) {
super(props);
this.onLogout = this.onLogout.bind(this);
}
onLogout() {
this.props.history.push('/');
}
render() {
return (
<div>
<h1>Your Links</h1>
<button onClick={this.onLogout}>Logout</button>
</div>
);
}
}
this.props.history.push('/cart');`を使ってカートページにリダイレクトすると、ヒストリーオブジェクトに保存されます。
お楽しみに、マイケル。
this.context.history.push`は動作しません。
私はなんとかこのようにしてpushを動作させることができました。
static contextTypes = {
router: PropTypes.object
}
handleSubmit(e) {
e.preventDefault();
if (this.props.auth.success) {
this.context.router.history.push("/some/Path")
}
}