React-router v4 this.props.history.push(...)无效

And*_*aro 28 reactjs react-router react-redux

我正在尝试以编程方式使用,this.props.history.push(..)但它似乎不起作用.

这是路由器:

import {
 BrowserRouter as Router,
 Route
} from 'react-router-dom';

<Router>
 <Route path="/customers/" exact component={CustomersList} />
 <Route path="/customers/:id" exact component="{Customer} />
</Router>
Run Code Online (Sandbox Code Playgroud)

在CustomerList中,呈现客户列表.单击客户(li)应该将应用程序路由到客户:

import { withRouter } from 'react-router'

class Customers extends Component {
  static propTypes = {
    history: PropTypes.object.isRequired
  }

 handleCustomerClick(customer) {
   this.props.history.push(`/customers/${customer.id}`);
 }

 render() {
   return(
    <ul>
      { this.props.customers.map((c) =>
        <li onClick={() => this.handleCustomerClick(c)} key={c.id}>
          {c.name}
        </li> 
    </ul>
  )

 }
}

//connect to redux to get customers

CustomersList = withRouter(CustomersList);
export default CustomersList;
Run Code Online (Sandbox Code Playgroud)

代码是部分的,但完全说明了情况.发生的情况是浏览器的地址栏相应地更改为history.push(..),但视图未更新,Customer组件未呈现且CustomersList仍然存在.有任何想法吗?

Del*_*hie 14

所以我来到这个问题,希望得到答案,但无济于事.我用过

const { history } = this.props;
history.push("/thePath")
Run Code Online (Sandbox Code Playgroud)

在同一个项目中,它按预期工作.经过进一步的实验和一些比较和对比,我意识到如果在嵌套组件中调用它,它将不会运行.因此,只有呈现的页面组件可以调用此函数才能使其正常工作.

在这里找到工作沙箱

  • 历史:v4.7.2
  • 反应:v16.0.0
  • react-dom:v16.0.0
  • react-router-dom:v4.2.2


cga*_*gat 11

在最新版本的反应路由器中,似乎情况有所改变.您现在可以通过上下文访问历史记录.this.context.history.push('/path')

另请参阅对此github问题的回复:https://github.com/ReactTraining/react-router/issues/4059


Jan*_*sek 7

对我来说(react-router v4,react v16)问题是我的导航组件没问题:

import { Link, withRouter } from 'react-router-dom'

class MainMenu extends Component {

  render() {
    return (
            ...
            <NavLink to="/contact">Contact</NavLink>
            ...
    );
  }
}

export default withRouter(MainMenu);
Run Code Online (Sandbox Code Playgroud)

两者都使用

to="/contact" 
Run Code Online (Sandbox Code Playgroud)

或者

OnClick={() => this.props.history.push('/contact')}; 
Run Code Online (Sandbox Code Playgroud)

行为仍然相同 - 浏览器中的 URL 已更改,但呈现了错误的组件,使用相同的旧 URL 调用路由器。

罪魁祸首是路由器定义。我不得不将 MainMenu 组件作为 Router 组件的子组件移动!

// wrong placement of the component that calls the router
<MainMenu history={this.props.history} />
<Router>
   <div>
     // this is the right place for the component!
     <MainMenu history={this.props.history} />
     <Route path="/" exact component={MainPage} />
     <Route path="/contact/" component={MainPage} />
   </div>
</Router>
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以通过withRouter高阶组件访问历史对象的属性和最接近的匹配。每当渲染时, withRouter都会将更新的匹配、位置和历史记录传递给包装的组件。

import React, { Component } from 'react'
import { withRouter } from 'react-router'; 
// you can also import "withRouter" from 'react-router-dom';

class Example extends Component {
    render() {
        const { match, location, history } = this.props
        return (
            <div>
                <div>You are now at {location.pathname}</div>
                <button onClick={() => history.push('/')}>{'Home'}</button>
            </div>
        )
    }
}


export default withRouter(Example)
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以尝试使用历史记录加载子组件。为此,请通过道具传递“历史”。像这样:

  return (
  <div>
    <Login history={this.props.history} />
    <br/>
    <Register/>
  </div>
)
Run Code Online (Sandbox Code Playgroud)

  • 看起来就是这样……而且非常悲伤 (3认同)