Jonty Tyagi
Jonty Tyagi

Reputation: 77

history.push() updates URL in browser but does not renders the appropriate component(Redirect not working too)

I am using react-router in my project and using this.props.history.push() inside componentDidMount() if the user is not looged in ,then redirect him to Login component. This is my code in App.js:


class App extends React.Component{

    constructor(props){
        super(props);
        
    }   
    
    componentDidMount(){
        
        firebase.auth().onAuthStateChanged((user)=>{
            if(user){
                this.props.dispatch(login(user.email)); 
            }
            else{
                
                this.props.history.push('/login');
            }
        })
    }
        render(){
        //console.log(this.props.isLoggedIn);
        return (<div className="App">
            <Switch>
                <Route path="/" component={()=><Homepage userName={this.props.username} logout={this.logout}/>} />
                <Route path="/login" component={Login} />
            </Switch>
        </div>);}
}


export default withRouter(connect(mapStateToProps)(App));

Below is my index.js code:

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';

const store= createStore(combineReducers({userState: userState}),applyMiddleware(logger));


ReactDOM.render(
    
        <Provider store={store}>
            <BrowserRouter>
                <App />
            </BrowserRouter>
        </Provider>
    ,
    document.getElementById('root')
);

Please not that I have removed some unnecessary functions and imports irrelevent to the context of this question.

Now let us come to what I have tried till now:

  1. Using Router instead of BrowserRouter with history object passed to it.
  2. Tried removing switch but that didn't work too.

I also searched for other questions that address this problem but unfortunately, none of them worked for me.

Please help me to find if there is any issue in my code.

Thank You!!

EDIT:

Looks like I'm having a bad day, even Redirect isn't working for me! I'm trying very hard but I don't understand why Login component is not being rendered even when the URL is being changed.

Upvotes: 2

Views: 1579

Answers (2)

Subrato Pattanaik
Subrato Pattanaik

Reputation: 6059

It seems like you didn't use exact in your Route component. If you don't use exact then react will route to / path first. It will reads the path(/login) as / + login. If you provide exact to this / path then react will route to the specified component which exactly matches the path. It is not necessary to provide an exact to all the Route component.

It is necessary when:

For example,

<Route exact path="/" component={About} />
<Route path="/login" component={Login} />

Then you need to provide the exact to parent path.

<Route exact path="/login" component={Login} />
<Route path="/login/profile" component={Profile} />

In short, if your next Route component path is a child of the previous path then you need to provide the exact property to the parent path.


Edited: There is one more thing that I'd like to say that in your Route component of / path you must have a render prop instead of a component prop for rendering the Callback component like this.
<Route exact path="/" render={()=><Homepage userName={this.props.username} logout={this.logout}/>} />

Some credits to @Sohaib answer. I have added some more explanation to his answer.

Upvotes: 1

Sohaib
Sohaib

Reputation: 11317

You need to use exact prop in your Route. Otherwise, /login will also match / first

            <Route exact path="/" component={()=><Homepage userName={this.props.username} logout={this.logout}/>} />
            <Route exact path="/login" component={Login} />

Upvotes: 3

Related Questions