我正在使用react-router with react js和i遵循他们的文档但面临此错误
编译时显示错误,
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;
答案 0 :(得分:16)
这是因为React Router在4.0.0开始时发生了变化。您现在应该在使用BrowserRouter
时使用react-router-dom
包中的browserHistory
。所以你的代码看起来像是:
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
元素,则必须按in this answer解释使用Switch
。
答案 1 :(得分:9)
对我来说,解决方案是改变
1)作为子组件
<Route path="/path">
<MyComponent/>
</Route>
到
2)组件作为“组件”道具
<Route path="/path" component={MyComponent}>
</Route>
它以两种方式呈现,所以对我来说很困惑,在examples中,它们提供了第一个示例中的代码。 (目前,我使用的是“ react-router-dom”软件包的5.1.2版本。)
更新
您也可以使用这种方式(对于子组件(“ 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
希望它对某人有帮助。
答案 2 :(得分:6)
答案 3 :(得分:6)
我的表单组件有问题。
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作为后端
答案 4 :(得分:2)
您可以使用window.location.href = '/somePath'
作为最后的选择
答案 5 :(得分:1)
以下解决方案适用于 ReactDOM.render :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<left>
<AnchorPane prefHeight="400.0" prefWidth="170.0" style="-fx-border-color: black; -fx-border-width: 0 2 0 0;" BorderPane.alignment="CENTER">
<children>
<ComboBox layoutY="2.0" prefHeight="25.0" prefWidth="170.0" />
<RadioButton layoutY="27.0" mnemonicParsing="false" text="RadioButton" />
<RadioButton layoutY="51.0" mnemonicParsing="false" text="RadioButton" />
<RadioButton layoutY="74.0" mnemonicParsing="false" text="RadioButton" />
<Label alignment="TOP_CENTER" layoutY="386.0" maxHeight="15.0" prefHeight="15.0" prefWidth="170.0" style="-fx-background-color: violet;" text="Label" AnchorPane.bottomAnchor="0.0" />
</children>
</AnchorPane>
</left>
<center>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<TextField layoutY="2.0" prefHeight="165.0" prefWidth="330.0" promptText="WITAM" text="heh" AnchorPane.bottomAnchor="25.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<HBox layoutX="14.0" layoutY="147.0" prefHeight="25.0" prefWidth="320.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="25.0" text="Button" />
<Button mnemonicParsing="false" text="Button" />
</children>
</HBox>
</children>
</AnchorPane>
</center>
</BorderPane>
它使用多个路由。
答案 6 :(得分:1)
在我看来,this.props.history没有定义,因为您没有将routeProps传递给要呈现的组件。
如下更改路线:
<Route path="/home" render={(routeProps) => <Home {...routeProps}/>} />
您还可以使用此方法将其他道具传递给渲染的组件。
答案 7 :(得分:1)
这对我有用>>>
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
将“react-router”更改为“react-router-dom”,将路由器更改为 BrowserRouter 作为路由器。
像这样>>>
import { BrowserRouter as Router, Route, browserHistory, IndexRoute } from 'react-router-dom';
答案 8 :(得分:1)
我试图在函数组件中使用 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 以获得更多理解。
答案 9 :(得分:0)
在尝试实例化自己的路由器而不是使用内置路由器之一来处理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 :(得分:0)
这应该在要路由到的组件中完成。在这种情况下,它是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;
答案 11 :(得分:0)
我有类似的东西:
<Router>
<HeaderComponent/>
<Router exact path="/" component={Home}/>
<Router path="/auth" component={AuthLayout}/>
<FooterComponent/>
</Router>
和AuthLayout
是我在SignIn
和SignUp
组件之间切换的组件,如下所示:
<div>
{ login ? <SignIn/> : <SignUp/> }
</div>
在这些组件中,我遇到了this.props.history is not a function
的错误。这是因为我没有直接在路由器内部使用这些组件。我可以访问this.props.history
内部的AuthLayout
,并且必须将其传递给它的子级。
所以我做到了:
<div>
{ login ? <SignIn history={this.props.history}/> : <SignUp history={this.props.history}/> }
</div>
问题解决了。
答案 12 :(得分:0)
检查是否有未链接到路由器的组件或组件之间不必要的链接。
除了您的可点击组件之一中有<Router><Link>...</Link></Router>
之外,它还可能使您的工作崩溃。
希望这会有所帮助。