1
votes

I have a react app that in the login method it is supposed to redirect to a /profile route. The path is changing, but the Profile component is not rendering. I think it may be something with the ordering of the routes or using exact path or not. I have tried using and from react-router-dom. Refreshing the page works but logs the current user out. The links work from the nav bar not the this.props.history.push(/profile). Thanks!

class App extends Component {
 constructor(props){
 super(props)
 this.state = {
  currentUser: null,
  loggedIn: false,
  unauthorizedUser: false
 }

this.handleLoginSubmit = this.handleLoginSubmit.bind(this);
 }

  async handleLoginSubmit(e) {
   e.preventDefault()
   const url = 'http://localhost:3000/auth/login';
   const options = {
   method: 'POST',
   headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
   },
   body: JSON.stringify({
    email: e.target[0].value,
    password: e.target[1].value
   })
  }

   await fetch(url, options)
    .then(res => res.status === 200 ? res.json() : "Unauthorized")
     .then(payload => {
      if (payload !== "Unauthorized") {
      window.localStorage.setItem("token", payload.token)
      this.setState({ loggedIn: true,
        currentUser: payload.user.id,
        unauthorizedUser: false,
        userfirstName: payload.user.firstName,
        userlastName: payload.user.lastName
      });
      console.log('current user is ' + this.state.currentUser)
      this.props.history.push(`/profile`);
      } else {
       this.setState({ loggedIn: false, unauthorizedUser: true })
      }
    })
    .catch(err => {
      console.log(err);
    })

 }

 render() {
   return (
  <div className="App">
    <Router>
      <div>
        <Nav loggedIn={this.state.loggedIn} handleLogout={this.handleLogout}/>
        <Route exact path='/profile' render={props => <Profile {...props} currentUser={this.state.currentUser} firstName={this.state.userfirstName} lastName={this.state.userlastName}/>} />
        <Route exact path='/' render={props => <HomePage {...props} handleLoginSubmit={this.handleLoginSubmit}
          handleSignUpSubmit={this.handleSignUpSubmit} unauthorizedUser = {this.state.unauthorizedUser} signUpError = {this.state.signUpError}
          loggedIn={this.state.loggedIn}/>}/>
        <Route exact path='/update' render={props => <UpdateUser {...props} currentUser={this.state.currentUser}/> }/>

        <Route exact path='/createoutfit' render={props => <AddOutfit {...props} currentUser={this.state.currentUser}/> }/>
        <Route exact path='/items' component={Items} />
        <Route exact path='/items/new' render={props => <AddItem {...props} currentUser={this.state.currentUser}/> } />
        <Route exact path='/outfits' render={props => <Outfit {...props} currentUser={this.state.currentUser}/> }/>
        <Route exact path='/add/itemstoOutfit' render={props => <AddItemsToOutfit {...props} currentUser={this.state.currentUser}/> }/>

        <Route exact path='/items/upload' component={FileUpload}/>

      </div>
    </Router>
  </div>
    );
  }
}

export default withRouter(App);
1
Please, show the Profile component code - Mikhail Sidorov

1 Answers

0
votes

I think you should run this.props.history.push code after setState operation will be completed, like this:

this.setState({ loggedIn: true,
    currentUser: payload.user.id,
    unauthorizedUser: false,
    userfirstName: payload.user.firstName,
    userlastName: payload.user.lastName
}, () => {
    console.log('current user is ' + this.state.currentUser)
    this.props.history.push(`/profile`);
});

https://reactjs.org/docs/react-component.html#setstate

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.