Skip to content

Instantly share code, notes, and snippets.

@waleedahmad
Last active November 24, 2020 23:52
Show Gist options
  • Save waleedahmad/9409ad4ec905feed82454d67ad0d9a14 to your computer and use it in GitHub Desktop.
Save waleedahmad/9409ad4ec905feed82454d67ad0d9a14 to your computer and use it in GitHub Desktop.
Re-render Navbar component when children component is replaced on redirect
var App = React.createClass({
getInitialState(){
return {
auth : false
}
},
checkAuth(){
var self = this;
$.ajax({
type : 'GET',
url : '/auth',
success : function(res){
if(res){
self.setState({
auth : true
});
}else{
self.setState({ auth : false});
}
}
});
},
render() {
return(
<div className="appWrapper">
<Navbar auth={this.state.auth}/>
<div className="container">
{this.props.children}
</div>
</div>
);
}
});
var Navbar = React.createClass({
getInitialState(){
return{
user_actions : '' ,
auth : this.props.auth
}
},
componentDidMount(){
this.checkAuth();
},
componentWillReceiveProps(nextProps){
this.setState({
auth : nextProps.auth
}, function(){
this.checkAuthState();
});
console.log(nextProps.auth);
},
checkAuth(){
var self = this;
$.ajax({
type : 'GET',
url : '/auth',
success : function(res){
if(res){
self.setState({
auth : true
});
}else{
self.setState({ auth : false});
}
self.checkAuthState();
console.log(self.state);
}
});
},
checkAuthState(){
if(!this.state.auth){
this.state.user_actions = <ul className="nav navbar-nav navbar-right">
<li><a href="/login">Login</a></li>
<li><a href="/register">Register</a></li>
</ul>;
this.setState({
user_actions : this.state.user_actions
});
}
if(this.state.auth){
this.state.user_actions = <ul className="nav navbar-nav navbar-right">
<li><a href="/logout">Logout</a></li>
</ul>;
this.setState({
user_actions : this.state.user_actions
});
}
},
render : function(){
return (
<nav className="navbar navbar-default">
<div className="container">
<a href="/" className="navbar-brand">Reactor</a>
{this.state.user_actions}
</div>
</nav>
);
}
});
var routes = (
<Router history={browserHistory}>
<Route path="/" component={require('./components/app')}>
<IndexRoute component={require('./components/dashboard/index')} onEnter={Auth.isAuthenticated}/>
<Route path="/register"
component={require('./components/authentication/register')}
onEnter={Auth.isNotAuthenticated} />
<Route path="/login"
component={require('./components/authentication/login')}
onEnter={Auth.isNotAuthenticated}/>
<Route path="*"
component={require('./components/404/404')}/>
</Route>
</Router>
);
@earlyseven
Copy link

How about changing this line

Navbar.js

checkAuthState(){

if(!this.state.auth){
    this.state.user_actions =   <ul className="nav navbar-nav navbar-right">
                                    <li><a href="/login">Login</a></li>
                                    <li><a href="/register">Register</a></li>
                                </ul>;
    this.setState({
        user_actions : this.state.user_actions
    });
}

if(this.state.auth){
    this.state.user_actions =   <ul className="nav navbar-nav navbar-right">
                                    <li><a href="/logout">Logout</a></li>
                                </ul>;
    this.setState({
        user_actions : this.state.user_actions
    });
}

}

TO THIS ONE

checkAuthState(){

var userActions =   <ul className="nav navbar-nav navbar-right">
                                    <li><a href="/login">Login</a></li>
                                    <li><a href="/register">Register</a></li>
                                </ul>;

if(this.state.auth){

userActions = <ul className="nav navbar-nav navbar-right">
                                    <li><a href="/logout">Logout</a></li>
                                </ul>;

}

this.setState({
    user_actions : userActions
});

}

@waleedahmad
Copy link
Author

I figured it out, i passed a method from App component to children component.

var App = React.createClass({

    getInitialState(){
        return {
            auth : false
        }
    },

    checkAuth(){
        var self = this;
        $.ajax({
            type : 'GET',
            url : '/auth',
            success : function(res){
                if(res){
                    self.setState({
                        auth : true
                    });
                }else{
                    self.setState({ auth : false});
                }
            }
        });
    },

    updateNavbar(){
        this.checkAuth();
    },

    render() {
        return(
            <div className="appWrapper">
                <Navbar auth={this.state.auth}/>
                <div className="container">
                    {React.cloneElement(this.props.children, {update: this.updateNavbar})}
                </div>
            </div>
        );
    }
});

When children component, for instance Login authenticates user, it calls update method passed as prop that will re-check for authentication, and makes change to App components auth state, that will trigger componentWillReceiveProps method on Navbar component with new props which will change state and re-render Navbar component. That's what i was trying to achieve.

var Login    =   React.createClass({
    getInitialState(){
        return {
            user : {email  : '', password : ''},
            auth_redirect : '',
            errors  : {},
            message : ''
        }
    },

    componentWillMount(){...},

    registerFormIsValid : function(){....},

    /**
     * Attempt login on Login form submit
     */
    validateUser : function(){
        var self = this;
        $.ajax({
            type : 'POST',
            url : '/login',
            data : {
                email : this.state.user.email,
                password : this.state.user.password
            },
            success : function(res){
                if(!res.auth){
                    toastr.error('Invalid Email or Password!');
                    self.setState({
                        message : <Alert message="Invalid Email or Password!"/>
                    });
                }else{
                    toastr.success('Successfully Authenticated!');
                    self.props.update(); // Check for update
                    self.context.router.push('/');
                }
            }
        });
    },

    Authenticate : function(event){....},

    saveUserState : function(event){...},

    render : function(){
        return (
            <div>
                <div className="login container">
                    <LoginForm
                        user={this.state.user}
                        onChange={this.saveUserState}
                        onSave={this.Authenticate}
                        errors={this.state.errors} />
                    {this.state.message}
                </div>
            </div>
        );
    }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment