React Router V4
で検証を行った後、新しいページに移動するにはどうすればよいですか?私はこのようなものを持っています:
export class WelcomeForm extends Component {
handleSubmit = (e) => {
e.preventDefault()
if(this.validateForm())
// send to '/life'
}
render() {
return (
<form className="WelcomeForm" onSubmit={this.handleSubmit}>
<input className="minutes" type="number" value={this.state.minutes} onChange={ (e) => this.handleChanges(e, "minutes")}/>
</form>
)
}
}
ユーザーを別のルートに送りたいのですが。リダイレクトを見ましたが、履歴から現在のページが削除されてしまいそうです。
react-router v4 を使用しているため、コンポーネントで withRouter を使用して履歴オブジェクトのプロパティにアクセスし、history.Push
を使用してルートを動的に変更する必要があります。
WithRouterの高次コンポーネントを介して、履歴オブジェクトのプロパティと最も近いものにアクセスできます。 withRouterは、ルートがレンダリング小道具と同じ小道具で変更されるたびに、そのコンポーネントを再レンダリングします:{match、location、history}。
このような:
import {withRouter} from 'react-router-dom';
class WelcomeForm extends Component {
handleSubmit = (e) => {
e.preventDefault()
if(this.validateForm())
this.props.history.Push("/life");
}
render() {
return (
<form className="WelcomeForm" onSubmit={this.handleSubmit}>
<input className="minutes" type="number" value={this.state.minutes} onChange={ (e) => this.handleChanges(e, "minutes")}/>
</form>
)
}
}
export default withRouter(WelcomeForm);
リダイレクトの動作に応じて、いくつかのオプションがあります: React router docs
リダイレクトコンポーネント
をレンダリングすると、新しい場所に移動します。新しい場所は、サーバー側のリダイレクト(HTTP 3xx)と同様に、履歴スタック内の現在の場所を上書きします。
to: string
-リダイレクト先のURL。to: object
-リダイレクト先の場所。Push: bool
-trueの場合、リダイレクトは現在のエントリを置き換えるのではなく、新しいエントリを履歴にプッシュします。
例:<Redirect Push to="/somewhere"/>
import { Route, Redirect } from 'react-router'
export class WelcomeForm extends Component {
handleSubmit = (e) => {
e.preventDefault()
if(this.validateForm())
<Redirect Push to="/life"/>
}
render() {
return (
<form className="WelcomeForm" onSubmit={this.handleSubmit}>
<input className="minutes" type="number" value={this.state.minutes} onChange={ (e) => this.handleChanges(e, "minutes")}/>
</form>
)
}
}
withRouter
HoCの使用
この高次コンポーネントは、ルートと同じ小道具を注入します。ただし、ファイルごとに1つのHoCしか持てないという制限があります。
import { withRouter } from 'react-router-dom'
export class WelcomeForm extends Component {
handleSubmit = (e) => {
e.preventDefault()
if(this.validateForm())
this.props.history.Push("/life");
}
render() {
return (
<form className="WelcomeForm" onSubmit={this.handleSubmit}>
<input className="minutes" type="number" value={this.state.minutes} onChange={ (e) => this.handleChanges(e, "minutes")}/>
</form>
)
}
}
withRouter
オブジェクトをプロパティとして挿入する高階コンポーネントを使用できます history
。次に、history.Push
を使用してリダイレクトを行うことができます。
import { withRouter } from 'react-router-dom';
...
class WelcomeForm extends Component {
handleSubmit = (e) => {
e.preventDefault()
if(this.validateForm())
this.props.history.Push('/life');
}
render() {
return (
<form className="WelcomeForm" onSubmit={this.handleSubmit}>
<input className="minutes" type="number" value={this.state.minutes} onChange={ (e) => this.handleChanges(e, "minutes")}/>
</form>
)
}
}
export default withRouter(WelcomeForm);
リダイレクトを行うには、場合によっては<Redirect to="/someURL" />
を使用することもできますが、このコンポーネントはレンダリングする必要があるため、JSXのどこかで使用する必要があります。
TypeScriptを使用している場合は、React.Component<RouteComponentProps>
を使用してコンポーネントを拡張し、this.props.history.Push
を適切に取得します
class YourComponent extends React.Component<RouteComponentProps> {
constructor(props: Readonly<RouteComponentProps>) {
super(props)
}
public render(){
// you can access history programmatically anywhere on this class
// this.props.history.Push("/")
return (<div/>)
}
}
return default withRouter(YourComponent)