Je travaille sur une fonctionnalité de connexion avec Facebook et je vois ce problème dans ma console. Il dit:
class SocialLogin extends Component{
constructor(props){
super(props);
this.state={
userData:""
};
}
componentDidMount() {
(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
console.log("d",d);
console.log("s",s);
console.log("id",id);
debugger
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
console.log("js",js);
js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
window.fbAsyncInit = ()=> {
window.FB.init({
appId: FACEBOOK_APP_ID,//Change with your Facebook app id
autoLogAppEvents: true,
xfbml: true,
version: 'v3.0'
});
window.FB.Event.subscribe('auth.statusChange', response => {
console.log("event",response);
debugger
if (response.authResponse) {
this.checkLoginState();
} else {
console.log('[FacebookLoginButton] User cancelled login or did not fully authorize.');
}
});
};
}
// componentDidUpdate(){
// console.log("updateduserprofile",userProfile);
// this.props.loginUser(userProfile);
// debugger
// //window.location.href="https://rooter-web-app-dev.firebaseapp.com/home/cricket"
// }
checkLoginState(){
debugger
window.FB.getLoginStatus(function(response) {
console.log("response inside checklogin",response);
this.statusChangeCallback(response);
}.bind(this));
}
login(){
window.FB.login(this.checkLoginState(), {scope: 'email'});
}
statusChangeCallback(response) {
console.log("response",response);
accessToken =response && response.authResponse && response.authResponse.accessToken;
if (response.status === 'connected') {
this.testAPI();
} else if (response.status === 'not_authorized') {
console.log("[FacebookLoginButton] Person is logged into Facebook but not your app");
} else {
console.log("[FacebookLoginButton] Person is not logged into Facebook");
}
}
testAPI() {
window.FB.api('/me' ,(response)=> {
console.log("testAPI",response);
if(response){
userProfile = {
auth:accessToken,
id:response.id,
name:response.name,
provider: "Facebook",
};
console.log("userProfile",userProfile);
this.setData(userProfile);
}
console.log('[FacebookLoginButton] Successful login for: ', response);
});
}
setData=(userProfile)=>{
this.setState({
userData:userProfile
},()=>{
console.log('inside setData');
if(userProfile!==undefined){
console.log("inside callback",userProfile);
this.props.loginUser(this.state.userData);
}
});
}
render(){
return (
<div style={loginstyle}>
<button onClick={()=>this.login() } className="loginBtn loginBtn--facebook">
Login with Facebook
</button>
</div>
)
} z
Je reçois le journal de la console de userProfile où nous voyons la réponse de Facebook et après cela, l'exécution du code s'arrête. Je ne vois pas ma connexion être distribuée à cause de cela, le setState devrait se produire.
Voici le code de connexion et nous ne faisons que setState d'une part.
Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
3 Réponses :
Le problème est que vous essayez de définir votre état une fois que votre composant a été démonté (ex: navigation vers une autre page). Donc, pour éviter que cela ne se produise, essayez celui-ci:
if(this._isMounted)
{
this.setData(userProfile);
}
Et dans ce testAPI ajoutez ceci:
_isMounted = false;
componentDidMount(){
this._isMounted = true;
}
componentWillUnmount(){
this._isMounted = false;
}
Et il ne mettra à jour l'état que si le composant est monté
avant de mettre à jour l'état du composant, vous devez vérifier s'il est monté ?? s'il n'est pas monté, ne mettez pas à jour l'état de celui-ci, pour ce faire, vous devrez maintenir l'indicateur indiquant l'état de montage du composant consiger le code suivant
constructor(props){
super(props);
this.state={
userData:""
};
//initially its false
this.mount=false
}
componentWillUnMount(){
//make it false here
this.mount=false;
}
componentDidMount() {
//make it true when mounted
this.mount=true;
}
maintenant avant d'utiliser setState, assurez-vous que this.mount est vrai, j'espère que cela vous aidera!
vous devez vous désabonner lorsque le composant sera démonté.
componentWillUnmmount() {
window.FB.Event.unsubscribe('auth.statusChange', this.onAuthStatusChange)
}
...
window.FB.Event.subscribe('auth.statusChange', this.onAuthStatusChange)
et lorsque le composant seraUnmmount
onAuthStatusChange = response => {
console.log("event",response);
if (response.authResponse) {
this.checkLoginState();
} else {
console.log('[FacebookLoginButton] User cancelled login or did not fully authorize.');
}
}