I am using react-router with react js and i following their documentation but facing this error
while compiling it shows the error,
TypeError: _this.
It seems to me that this.props.history is not defined, because you did not pass the routeProps to the component you want to render.
Change your routes as follows:
<Route path="/home" render={(routeProps) => <Home {...routeProps}/>} />
You can also pass other props to the rendered components using this method.
This should be done in the component that is being routed to. In this case, it is App component. Therefore, in App.js, import "createBrowserHistory" and do it as follows:
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;
This is because things changed in React Router starting with 4.0.0. You should now use BrowserRouter
from react-router-dom
package when you were using browserHistory
. So your code will looks like:
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')
);
Of course, you'll need to install react-router-dom
first.
Also note that if you're using more than one Route
element, you'll have to use a Switch
as explained in this answer.
Check that if there are any components that you haven't linked to router or any links that is not necessary among your components.
Besides if you have <Router><Link>...</Link></Router>
in one of your clickable components it might crash your work.
Hope it might help.
I have problems with my Form component.
this.props.history.push('/') is undefined.
to solve this i added
import {withRouter} from 'react-router-dom'
And then export default component as: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));
I hope this is useful for someone. I am using Django as a backend
I had something like:
<Router>
<HeaderComponent/>
<Router exact path="/" component={Home}/>
<Router path="/auth" component={AuthLayout}/>
<FooterComponent/>
</Router>
and AuthLayout
was a component in which I was switching between SignIn
and SignUp
components, like below:
<div>
{ login ? <SignIn/> : <SignUp/> }
</div>
I faced this error of this.props.history is not a function
inside these components. It was because I hadn't used those components directly inside the router. I had access to this.props.history
inside the AuthLayout
and I had to pass it to its children.
So I did it:
<div>
{ login ? <SignIn history={this.props.history}/> : <SignUp history={this.props.history}/> }
</div>
and the problem solved.