Réagir setState() pas de mise à jour de l'état après $.ajax() demande
Je suis l'aide de réagir avec réagissent-routeur. Après vérification de l'authentification avec onEnter Asynchrone crochet sur IndexRoute, App composant est rendu. App composant a un état initial auth, qui est indéfinie lorsqu'il rend. auth état est passé à la barre de navigation de la composante prop où il sera utilisé pour décider si ou de ne pas montrer de connexion, d'inscription et de déconnexion des liens.
Lors de l'Application de la composante est de fait rendu, componentDidMount()
fait un appel ajax à nouveau pour vérifier si l'utilisateur est authentifié. Sur la réponse de changement à l'état. Après le changement d'état d'une requête ajax, je suis la journalisation de l'état de la console, this.setState()
méthode ne change pas d'état mais de toute façon toujours des déclencheurs componentWillReceiveProps() la méthode sur la barre de navigation de composant et this.props.auth
valeur est toujours pas défini.
//Checks Authentication Asynchronously
isAuthenticated(nextState, replace, callback) {
$.ajax({
type : 'GET',
url : '/auth',
success : function(res){
if(!res){
callback(replace({ pathname: '/login', query: { auth: 'false' } }));
}else{
callback();
}
}
});
};
//routes
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>
);
//App
const App = React.createClass({
getInitialState(){
return {
auth : undefined
}
},
componentDidMount(){
console.log('App componentDidMount');
this.checkAuth();
},
checkAuth(){
var self = this;
$.ajax({
type : 'GET',
url : '/auth',
success : function(res){
if(res){
self.setState({
auth : true
});
}else{
self.setState({ auth : false});
}
}
});
console.log(this.state.auth);
},
render() {
return(
<div className="appWrapper">
<Navbar auth={this.state.auth}/>
<div className="container">
{this.props.children}
</div>
</div>
);
}
});
//Navbar
var Navbar = React.createClass({
getInitialState(){
return{
user_actions : '' ,
auth : this.props.auth
}
},
componentDidMount(){
console.log('Navbar componentDidMount ', this.props.auth);
this.checkAuthState();
},
componentWillReceiveProps(){
console.log('Navbar componentWillReceiveProps ', this.props.auth);
this.setState({
auth : this.props.auth
});
this.checkAuthState();
},
checkAuthState(){
console.log('Nav Mounted with auth : ', this.state.auth);
if(this.state.auth == undefined){
this.state.user_actions = '';
}
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>
);
}
});
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, je vous suggère de relire React.JS de la documentation, car il ya quelques choses qui doivent être noté:
tl;dr;
Revenons à la question:
1. Ajax réponse est la modification d'un état de la valeur, mais la valeur n'est pas de changer dans votre journal.
Vous ne le verrez pas si vous imprimez la valeur après une requête ajax! La raison en est:
Tout d'abord, vous êtes en train de faire requête asynchrone à l'aide d'Ajax et d'essayer de voir le résultat en synchrone façon. JS exécutera votre
console.log
premier qui contient toujours la valeur avant de demander, puis effectuer une requête ajax de rappel. C'est le bloc de votre code:Deuxième, vous ne pourrez pas voir le changement de la valeur de l'état de droit après que vous avez défini une nouvelle valeur de l'état. Par exemple, supposons que la valeur de
this.state.auth
estfalse
:Vous êtes en mesure de voir votre nouvel état de la valeur en utilisant
componentWillUpdate(nextProps, nextState)
méthode. Vous pouvez lire à ce sujet à partir de ce lien: React.JS Composant Spécifications et Cycle de vie2. Déclenche toujours componentWillReceiveProps() la méthode sur la barre de navigation de composant et présent.accessoires de jeu.auth valeur est toujours pas défini.
Cela signifie que votre valeur de l'état est modifié avec succès par
setState()
sur votre réponse ajax. La preuve en est Navbar composant de recevoir un nouveau accessoires qui l'envoyer par Application de la composante (où l'auth état est changé) qui va déclenchercomponentWillReceiveProps()
méthode.Peut-être que votre code devrait ressembler à ceci:
Espère que cela aide!
success: (data) =>{...}
alors vous n'avez pas besoin de laself
variable.En ajax portée. il est impossible d'accéder à réagir état. comme alternative, vous pouvez appeler d'autres méthode dans le module ajax réussite d'appel, puis la mise à jour de l'état là.
suivre cet exemple.
consultez la Documentation de componentWillReceiveProps:
https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
Lors de vos propriétés va changer, puis l'accès aux propriétés "nextProps". Sinon, vous aurez accès à la vieille propriétés.
Comme une petite astuce:
Inclure votre checkAuthState() code dans la méthode render, pas dans le componentDidMount méthode parce que, par conséquent, vous pouvez éviter que votre setState appel.
Suffit d'utiliser la flèche des fonctions pour accéder à cette: