React-router TypeError:_this.props.history 未定义

Posted

技术标签:

【中文标题】React-router TypeError:_this.props.history 未定义【英文标题】:React-router TypeError: _this.props.history is undefined 【发布时间】:2017-08-08 23:55:51 【问题描述】:

我正在使用带有 react js 的 react-router,我按照他们的文档进行操作,但遇到了这个错误

编译时显示错误,

TypeError: _this.props.history is undefined

这是我的 index.js 文件

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import  Router, Route, browserHistory, IndexRoute  from 'react-router';

ReactDOM.render(
  <Router history=browserHistory>
    <Route path="/" component=App>

    </Route>
  </Router>
  ,
  document.getElementById('root')
);

这是我的 App.js 文件

import React,  Component  from 'react';
import './App.css';

class App extends Component 
    constructor(props)
        super(props);

        this.state = 
            headerText: "Props from Header.",
            contentText: "Props from content."
        ;
    
    render() 
        return (
          <div className="App">
            <ul>
                <li><a href="">Home</a></li>
                <li><a href="">Home</a></li>
                <li><a href="">Home</a></li>
            </ul>
          </div>
        );
    


export default App;

【问题讨论】:

你从哪里叫的? 我在 index.js 文件中使用了路由器,您可以从代码中看到这一点。 【参考方案1】:

这是因为 React Router 从 4.0.0 开始发生了变化。当您使用browserHistory 时,您现在应该使用来自react-router-dom 包的BrowserRouter。所以你的代码看起来像:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import  BrowserRouter, Route  from 'react-router-dom';

ReactDOM.render(
    <BrowserRouter>
        <Route path="/" component= App />
    </BrowserRouter>, document.getElementById('root')
);

当然,你需要先安装react-router-dom

另请注意,如果您使用多个Route 元素,则必须使用Switch,如in this answer 所述。

【讨论】:

【参考方案2】:

对我来说,解决办法是改变

1) 子组件

<Route path="/path">
 <MyComponent/>
</Route>

2) 组件作为“组件”道具

<Route path="/path" component=MyComponent>
</Route>

它以两种方式呈现,所以对我来说非常困惑,在examples 他们提供的代码与第一个示例一样。 (我目前使用的是 5.1.2 版的“react-router-dom”包)。

更新

您也可以使用这种方式(对于子组件(“MyComponent”的子组件)仅适用于这个)

import withRouter from 'react-router-dom';

const componentClassWithHistory = withRouter(ChildComponent);
export componentClassWithHistory as ChildComponent;

或默认导出

export default withRouter(ChildComponent)

或用于打字稿

const componentClassWithHistory = (withRouter(ChildComponent as any) as any);
export componentClassWithHistory as ChildComponent;

来源:https://reacttraining.com/react-router/core/api/withRouter

希望对某人有所帮助。

【讨论】:

对于功能组件最好使用useHistory钩子; 这里也一样,但我想将我的组件保留为子组件。您可以通过向每个组件添加 2 行来启用 withRouter 来做到这一点: 1) import withRouter from 'react-router-dom'; 2) 用Router(Home)导出默认值;这解决了我所有的问题。这个家伙博客的完整细节:dev.to/kozakrisz/…【参考方案3】:

你在使用 npm 吗?我的 package.json 中的“react-router”:“^4.0.0”也有同样的问题。将其更改为 "react-router": "^3.0.2" 解决了我的问题。

【讨论】:

"react-router": "^3.0.2" 对我有用。但不明白为什么 4.0.0 不起作用。 我也是)我只是将它与我​​上次工作的 package.json 进行了比较。 当你按照官方教程学习并且第 1 课不起作用时,这不是一个好兆头:>【参考方案4】:

我的表单组件有问题。

this.props.history.push('/') 未定义。

为了解决这个问题,我添加了import withRouter from 'react-router-dom' 然后将默认组件导出为: export default withRouter(connect(mapStateToProps)(CustomForm));

import React from "react";
import  Form, Input, Button  from "antd";
import  connect  from "react-redux";
import withRouter from 'react-router-dom'
import axios from "axios";

const FormItem = Form.Item;


class CustomForm extends React.Component 

  handleFormSubmit = async (event, requestType, articleID, ) => 
    event.preventDefault();

const postObj = 
  title: event.target.elements.title.value,
  content: event.target.elements.content.value


axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.headers = 
  "Content-Type": "application/json",
  Authorization: `Token $this.props.token`,
;

if (requestType === "post") 
  await axios.post("http://127.0.0.1:8000/api/create/", postObj)
    .then(res => 
      if (res.status === 201) 
        this.props.history.push(`/`);
      
    )
 else if (requestType === "put") 
  await axios.put(`http://127.0.0.1:8000/api/$articleID/update/`, postObj)
    .then(res => 
      if (res.status === 200) 
        this.props.history.push(`/`);
      
    )



;

  render() 
    return (
      <div>
        <Form
          onSubmit=event =>
            this.handleFormSubmit(
              event,
              this.props.requestType,
              this.props.articleID
            )
          
        >
          <FormItem label="Title">
            <Input name="title" placeholder="Put a title here" />
          </FormItem>
          <FormItem label="Content">
            <Input name="content" placeholder="Enter some content ..." />
          </FormItem>
          <FormItem>
            <Button type="primary" htmlType="submit">
              this.props.btnText
            </Button>
          </FormItem>
        </Form>
      </div>
    );
  


const mapStateToProps = state => 
  return 
    token: state.token
  ;
;

export default withRouter(connect(mapStateToProps)(CustomForm));

我希望这对某人有用。我使用 Django 作为后端

【讨论】:

谢谢,这正是我的菜鸟错误。【参考方案5】:

您可以使用window.location.href = '/somePath' 作为最后的手段

【讨论】:

它正在工作,但此方法正在刷新我的页面。【参考方案6】:

这对我有用>>>

import  Router, Route, browserHistory, IndexRoute  from 'react-router';

将 'react-router' 更改为 'react-router-dom',将 Router 更改为 BrowserRouter 作为路由器。

像这样>>>

import  BrowserRouter as Router, Route, browserHistory, IndexRoute  from 'react-router-dom';

【讨论】:

【参考方案7】:

我试图在功能组件中使用history,但它未定义,因为我试图使用props 访问它。 根据文档,我们需要使用useHistory 挂钩来访问历史记录。这是根据文档的示例代码。

import  useHistory  from "react-router-dom";
function HomeButton() 


 let history = useHistory();

  function handleClick() 
    history.push("/home");
  

  return (
    <button type="button" onClick=handleClick>
      Go home
    </button>
  );

您可以查看此link 以获得更多了解。

【讨论】:

【参考方案8】:

在我看来 this.props.history 没有定义,因为你没有将 routeProps 传递给你要渲染的组件。

如下改变你的路线:

 <Route path="/home" render=(routeProps) => <Home ...routeProps/> />

您还可以使用此方法将其他道具传递给渲染的组件。

【讨论】:

这只是在搜索了几个小时后为我省去了很多麻烦。非常感谢。 @Overcomer 乐于助人:) 这实际上解决了 react-router 5.2 的问题。可能不是最好的方法,但由于我使用的是旧代码和升级框架,所以速度更快【参考方案9】:

我在尝试实例化自己的路由器而不是使用内置路由器之一来处理an issue of having access to the history时遇到了这个问题:

history.js

import  createHashHistory as createHistory  from 'history'

export default createHistory()

root.jsx

import  Router, Route  from 'react-router-dom'
import history from './history'

...

  <Router history=history>
    <Route path="/test" component=Test/>
  </Router>

就我而言,问题在于我将 history 包的一个版本锁定在 v2.1.2,而 react-router 在其自身的依赖项中依赖于 history 的 v4.x 版本。所以内置路由器使用较新的history 可以很好地实例化,但是当我自己尝试这样做时,我正在拉入较旧的history 并得到一个不兼容的对象。

【讨论】:

【参考方案10】:

我有类似的东西:

<Router>
   <HeaderComponent/>
   <Router exact path="/" component=Home/>
   <Router path="/auth" component=AuthLayout/>
   <FooterComponent/>
 </Router>

AuthLayout 是一个组件,我在其中切换SignInSignUp 组件,如下所示:

<div>
   login ? <SignIn/> : <SignUp/> 
</div>

我在这些组件中遇到了this.props.history is not a function 的错误。这是因为我没有直接在路由器内部使用这些组件。我可以访问AuthLayout 中的this.props.history,我必须将它传递给它的孩子。

所以我做到了:

<div>
   login ? <SignIn history=this.props.history/> :  <SignUp history=this.props.history/> 
</div>

问题解决了。

【讨论】:

【参考方案11】:

以下解决方案适用于 ReactDOM.render

 <BrowserRouter>
  <Switch>
    <Route path="/home" component=Home />
    <Route path="/user" component=User />
    <Route path="*" component=page404 />
  </Switch>
 </BrowserRouter>

它使用多个路由。

【讨论】:

【参考方案12】:

这应该在被路由到的组件中完成。在这种情况下,它是 App 组件。因此,在 App.js 中,导入“createBrowserHistory”,如下所示:

import React,  Component  from 'react';
import './App.css';
import  createBrowserHistory  from "history";

class App extends Component 
    constructor(props)
        super(props);

        this.history = createBrowserHistory();;

        this.state = 
            headerText: "Props from Header.",
            contentText: "Props from content."
        ;
    
    render() 
        return (
          <div className="App">
            <ul>
                <li><a href="">Home</a></li>
                <li><a href="">Home</a></li>
                <li><a href="">Home</a></li>
            </ul>
          </div>
        );
    


export default App;

【讨论】:

【参考方案13】:

检查是否有任何组件未链接到路由器或组件之间没有必要的链接。

此外,如果您的一个可点击组件中有&lt;Router&gt;&lt;Link&gt;...&lt;/Link&gt;&lt;/Router&gt;,它可能会导致您的工作崩溃。

希望对您有所帮助。

【讨论】:

以上是关于React-router TypeError:_this.props.history 未定义的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:使用来自 react-router 的 useParams 时无法读取未定义的属性“匹配”

渲染中的错误:“TypeError:无法读取未定义的属性'_t'”在使用 Jest 的单元测试中

如何使用 react-router 通过 Route 渲染传递 redux 商店道具?

错误:TimeoutException Future 未完成并且 TypeError:T.as 不是 _Future.new 的函数。[_setValue]

TypeError: can't pickle _thread.lock objects

rxjs TypeError:this._complete不是函数