Home > Software design >  React: TypeError cannot read properties of undefined (reading 'push')
React: TypeError cannot read properties of undefined (reading 'push')

Time:09-27

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);
  • Related