在 React-Router v4 中以编程方式导航

Programmatically navigating in React-Router v4

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>
        )
    }
}

我想将用户转到另一条路线。我查看了 Redirect,但它似乎会从我不想要的历史记录中删除当前页面。

您在组件中使用 react-router v4, so you need to use withRouter 来访问历史对象的属性,然后使用 history.push 动态更改路由。

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 }.

像这样:

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

重定向组件

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 - 要重定向到的 URL。
to: object - 要重定向到的位置。
push: bool - 如果为真,重定向会将新条目推送到历史记录中,而不是替换当前条目。

示例:<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

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>
            )
        }
    }

您可以将 withRouter higher-order component which will inject 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)