问题
How can I move to a new page after some validation is done with React Router V4? I have something like this:
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>
)
}
}
I would like to send the user to another route. I had a look at Redirect but it seems like it would delete the current page from the history which I don't want.
回答1:
You are using react-router v4, so you need to use withRouter with your component to access the history object’s properties, then use history.push to change the route dynamically.
withRouter:
You can get access to the history object’s properties and the closest 's match via the withRouter higher-order component. withRouter will re-render its component every time the route changes with the same props as render props: { match, location, history }.
Like this:
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);
回答2:
Depending on how you want your redirect to behave there are several options: React router docs
Redirect component
Rendering a will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects (HTTP 3xx) do.
to: string - The URL to redirect to.to: object - A location to redirect to.push: bool - When true, redirecting will push a new entry onto the history instead of replacing the current one.
Example: <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>
)
}
}
Using withRouter HoC
This higher order component will inject the same props as Route. However, it carries along the limitation that you can have only 1 HoC per file.
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>
)
}
}
回答3:
You can use withRouter higher-order component which will inject history object as property. Then you can use history.push to make redirection:
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);
To make redirection you can also use <Redirect to="/someURL" /> in some cases but this component have to be rendered so you have to use it somewhere in JSX.
回答4:
If you are using TypeScript extends your component using React.Component<RouteComponentProps> to get this.props.history.push properly
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)
来源:https://stackoverflow.com/questions/44137774/programmatically-navigating-in-react-router-v4