私はReactJSとReact-Routerが初めてです。プロップを通してreact-routerから<Link/>
オブジェクトを受け取るコンポーネントがあります。ユーザーがこのコンポーネント内の「次へ」ボタンをクリックするたびに、手動で<Link/>
オブジェクトを呼び出したいです。
今は、refsを使ってバッキングインスタンスにアクセスし、<Link/>
が生成する 'a'タグを手動でクリックしています。 。
質問:手動でリンクを呼び出す方法はありますか(例:this.props.next.go
)。
これは私が持っている現在のコードです:
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />
//in Document.js
...
var Document = React.createClass({
_onClickNext: function() {
var next = this.refs.next.getDOMNode();
next.querySelectorAll('a').item(0).click(); //this sounds like hack to me
},
render: function() {
return (
...
<div ref="next">{this.props.next} <img src="rightArrow.png" onClick={this._onClickNext}/></div>
...
);
}
});
...
これは私が欲しいコードです:
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
<Document next={sampleLink} />
//in Document.js
...
var Document = React.createClass({
render: function() {
return (
...
<div onClick={this.props.next.go}>{this.props.next.label} <img src="rightArrow.png" /> </div>
...
);
}
});
...
V4の推奨される方法はあなたのrenderメソッドがリダイレクトをキャッチできるようにすることです。 stateまたはpropsを使用して、リダイレクトコンポーネントを表示する必要があるかどうかを判断します(これによりリダイレクトがトリガーされます)。
import { Redirect } from 'react-router';
// ... your class implementation
handleOnClick = () => {
// some action...
// then redirect
this.setState({redirect: true});
}
render() {
if (this.state.redirect) {
return <Redirect Push to="/sample" />;
}
return <button onClick={this.handleOnClick} type="button">Button</button>;
}
参照先: https://reacttraining.com/react-router/web/api/Redirect
Reactコンポーネントに公開されているRouter
のコンテキストを利用することもできます。
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
Push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
};
handleOnClick = () => {
this.context.router.Push('/sample');
}
これが<Redirect />
が内部でどのように機能するかです。
それでもv2の実装と同様のことをする必要がある場合は、BrowserRouter
のコピーを作成してからhistory
をエクスポート可能な定数として公開することができます。以下は基本的な例ですが、必要に応じてカスタマイズ可能な小道具でそれを注入するためにそれを構成することができます。ライフサイクルに関する注意点がありますが、v2の場合と同様に、常にルーターを再表示する必要があります。これは、アクション関数からのAPIリクエスト後のリダイレクトに役立ちます。
// browser router file...
import createHistory from 'history/createBrowserHistory';
import { Router } from 'react-router';
export const history = createHistory();
export default class BrowserRouter extends Component {
render() {
return <Router history={history} children={this.props.children} />
}
}
// your main file...
import BrowserRouter from './relative/path/to/BrowserRouter';
import { render } from 'react-dom';
render(
<BrowserRouter>
<App/>
</BrowserRouter>
);
// some file... where you don't have React instance references
import { history } from './relative/path/to/BrowserRouter';
history.Push('/sample');
拡張する最新のBrowserRouter
: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
新しい状態をbrowserHistory
インスタンスにプッシュします。
import {browserHistory} from 'react-router';
// ...
browserHistory.Push('/sample');
参照: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
React Router 4には withRouterHOC が含まれています。これにより、this.props
を介してhistory
オブジェクトにアクセスできます。
import React, {Component} from 'react'
import {withRouter} from 'react-router-dom'
class Foo extends Component {
constructor(props) {
super(props)
this.goHome = this.goHome.bind(this)
}
goHome() {
this.props.history.Push('/')
}
render() {
<div className="foo">
<button onClick={this.goHome} />
</div>
}
}
export default withRouter(Foo)
あるいはonClickを実行してみることもできます(もっと暴力的な解決策):
window.location.assign("/sample");
V4ではcontextを使ってPushメソッドを簡単に呼び出すことができます。
this.context.router.Push(this.props.exitPath);
コンテキストは次のとおりです。
static contextTypes = {
router: React.PropTypes.object,
};
わかりました、私はそれのための適切な解決策を見つけることができたと思います。
さて、<Link/>
をpropとしてDocumentに送る代わりに、私はreact-router Link用のカスタムラッパーである<NextLink/>
を送ります。そうすることで、Documentオブジェクトの中に宛先コードを入れることを避けながら、Link構造の一部として右矢印を持つことができます。
更新されたコードは次のようになります。
//in NextLink.js
var React = require('react');
var Right = require('./Right');
var NextLink = React.createClass({
propTypes: {
link: React.PropTypes.node.isRequired
},
contextTypes: {
transitionTo: React.PropTypes.func.isRequired
},
_onClickRight: function() {
this.context.transitionTo(this.props.link.props.to);
},
render: function() {
return (
<div>
{this.props.link}
<Right onClick={this._onClickRight} />
</div>
);
}
});
module.exports = NextLink;
...
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
var nextLink = <NextLink link={sampleLink} />
<Document next={nextLink} />
//in Document.js
...
var Document = React.createClass({
render: function() {
return (
...
<div>{this.props.next}</div>
...
);
}
});
...
P.S:最新バージョンのreact-routerを使用している場合は、this.context.router.transitionTo
の代わりにthis.context.transitionTo
を使用する必要があるかもしれません。このコードはreact-routerバージョン0.12.Xのためにうまく働きます。
再びこれはJSです:)これはまだ動作します....
var linkToClick = document.getElementById('something');
linkToClick.click();
<Link id="something" to={/somewhaere}> the link </Link>