I am trying to create an app with a login functionality. The way I want it to work is that once the login is verified, the program would automatically redirect the user towards the homepage. Right now I have this code:
App.js:
function App() {
return (
<React.Fragment>
<div className="content">
<BrowserRouter>
<Routes>
<Route element={<LoginForm />} path="/login" />
<Route path="/test" element={<BasicExample />} />
</Routes>
</BrowserRouter>
</div>
</React.Fragment>
);
}
export default App;
Login
class LoginForm extends FForm {
// create a ref object
state = {
data: { username: "", password: "" },
errors: {},
};
handleSubmit = event => {
event.preventDefault();
const { email, password } = this.state;
// console.log(this.state);
console.log('logging')
axios
.post(
"http://127.0.0.1:8000/auth/",
{
username: email,
password: password
}
// { withCredentials: true }
)
.then(res => {
console.log('got it')
console.log(res);
window.localStorage.setItem("token", res.data.token);
console.log('pushing')
this.props.history.push('/test', { state: "sample data" })
// return <Redirect to="/home" />;
})
.catch(err => {
console.log('NOOOOO eror')
console.log(err);
});
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<h1>welcome to log in!</h1>
<br />
<input
type="text"
name="email"
placeholder="Username"
defaultValue={this.state.email}
onChange={e => {
this.setState({ email: e.target.value });
}}
/>
<br />
<br />
<input
type="password"
name="password"
placeholder="Password"
defaultValue={this.state.password}
onChange={e => {
this.setState({ password: e.target.value });
}}
/>
<br />
<br />
<button type="submit"> Login </button>
</form>
</div>
);
}
}
export default LoginForm;
The code outputs TypeError
: cannot read properties of undefined (reading 'push'). I assume that the history was not initialized. Where/how should I initialize the history?
CodePudding user response:
For react-router 6 continue to use element, but use a HOC
Ok, react-router 6 changed the way they do things to only use element, but you have to pass props yourself, and if you're using a class based component then you need to use a HOC)
const LoginComponentWithHistory = (props) => <LoginForm {...props} history={useHistory()}/>
// route
<Route element={<LoginFormWithHistory/>} path="/login" />
See related interesting github convo: https://github.com/remix-run/react-router/issues/8146
For react-router 5
This needs to be passed as component
<Route component={LoginForm} path="/login" />
When you pass it as component
, react-router passes in all the props for you (including history)
CodePudding user response:
Try exporting LoginForm
with HOC from React Router
export default withRouter(LoginForm);