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

IT技术 reactjs react-router react-router-v4
2021-03-29 00:35:28

完成某些验证后如何移动到新页面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>
        )
    }
}

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

4个回答

您正在使用react-router v4,因此您需要将withRouter与您的组件一起使用以访问历史对象的属性,然后使用它history.push来动态更改路由。

带路由器

您可以通过 withRouter 高阶组件访问历史对象的属性和最接近的匹配项。每次路由更改时,withRouter 都会使用与渲染props相同的props重新渲染其组件:{匹配,位置,历史}。

像这样:

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);
谢谢,我试过了,它给了我这个错误:'TypeError:无法读取未定义的属性'push'。有没有更简单的方法?
2021-05-27 00:35:28
使用这个:this.props.history.push("/life");检查更新的答案。
2021-06-02 00:35:28
是的,它似乎有效。我想了解为什么其他答案中解释的重定向似乎不起作用,两者中哪一个是更好的做法
2021-06-05 00:35:28
啊谢谢!是的,我export default withRouter(LoginContainer)在出口声明中遗漏
2021-06-05 00:35:28
两种方式都是正确的,但是当你渲染它时重定向会起作用,这意味着它是一个 ui 组件,所以在渲染方法内部使用一些条件并从那里返回重定向它会起作用,但在那个答案中,他只是把它放在一个方法中在这种情况下,我认为这是行不通的。
2021-06-13 00:35:28

您可以使用withRouterhistory对象作为属性注入的高阶组件然后你可以使用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 中的某处使用它。

亲爱的投票者请解释为什么你拒绝我的回答。
2021-05-27 00:35:28

根据您希望重定向的行为方式,有多种选择:React router docs

重定向组件

渲染 a 将导航到新位置。新位置将覆盖历史堆栈中的当前位置,就像服务器端重定向 (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>
        )
    }
}

使用withRouterHoC

这个高阶组件将注入与 Route 相同的 props。但是,它存在每个文件只能有 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>
            )
        }
    }
你确定它会起作用吗?根据文档,仅渲染 a<Redirect>将导航到新位置。你不渲染它。
2021-05-27 00:35:28
如果您添加push它将保留历史记录。
2021-05-29 00:35:28
添加推送在哪里?
2021-06-01 00:35:28
嘿谢谢。正如我在问题中所写,我担心重定向会从浏览器历史记录中删除当前页面
2021-06-06 00:35:28
恐怕它不起作用:它说:'期望赋值或函数调用,而是看到一个表达式 no-unused-expressions'
2021-06-17 00:35:28

如果您使用 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)