I am working on a login logout components and everything is working fine but sometimes this error pops up Can't perform a React state update 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 i have searched on internet and tried many solutions but nothing is working for me
here is my login component
class Login extends Component {
_isMounted = false;
constructor(props) {
super(props)
let token = localStorage.getItem("Token")
let isloggedIn = true
if (token == null) {
isloggedIn = false
}
let authToken = undefined
this.state = {
userName: undefined,
userPassword: undefined,
isToken: false,
isloggedIn,
authToken
}
}
componentDidMount(){
this._isMounted = true;
}
componentWillUnmount() {
this._isMounted = false;
}
SetUserName = (event) => {
this.setState({ userName: event.target.value })
}
SetUserPassword = (event) => {
this.setState({ userPassword: event.target.value })
}
SubmitHandler = (e) => {
e.preventDefault();
this._isMounted = true;
console.log("button clicked")
var reqData = {
"username": this.state.userName,
"password": this.state.userPassword,
"grant_type": "password"
};
axios({
method: 'post',
url: 'http://192.168.100.35/token',
withCredentials: true,
crossdomain: true,
data: $.param(reqData),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache",
}
}).then(response => {
if (this._isMounted) {
console.log(response.data)
this.setState({ isToken: true })
this.setState({ isloggedIn: true })
this.setState({ authToken: response.data.access_token })
localStorage.setItem("Token", this.state.authToken)
}
})
}
render() {
if (this.state.isloggedIn) {
return <Redirect to="/getStudentsByClass" />
}
return (
<div className="Login">
<div className="c-card u-mb-xsmall">
<header className="c-card__header u-pt-large">
<a>
</a>
<h1 className="u-h3 u-text-center u-mb-zero">Welcome Back! Please Login.</h1>
</header>
<form className="c-card__body">
<div className="c-field u-mb-small">
<label className="c-field__label">
Log in with your e-mail address
</label>
<input className="c-input" value={this.state.userName} onChange={this.SetUserName} type="text" placeholder="[email protected]"></input>
</div>
<div className="c-field u-mb-small">
<label className="c-field__label">
Password
</label>
<input className="c-input" value={this.state.userPassword} onChange={this.SetUserPassword} type="password" placeholder="Letters, Numbers"></input>
</div>
<button className="c-btn c-btn--info c-btn--fullwidth"
onClick={this.SubmitHandler}>
Sign in to Dashboard
</button>
<span className="c-divider c-divider--small has-text u-mv-medium">
Login Via Social Networks
</span>
<div className="o-line">
<a className="c-icon u-bg-twitter">
<i className="fa fa-twitter"></i>
</a>
<a className="c-icon u-bg-facebook">
<i className="fa fa-facebook"></i>
</a>
<a className="c-icon u-bg-pinterest">
<i className="fa fa-pinterest"></i>
</a>
<a className="c-icon u-bg-dribbble">
<i className="fa fa-dribbble"></i>
</a>
</div>
</form>
</div>
<div className="o-line">
<a className="u-text-mute u-text-small">
Don’t have an account yet? Get Started
</a>
<a className="u-text-mute u-text-small">
Forgot Password?
</a>
</div>
</div>
)
}
}
here is my logout component
class Logout extends Component{
constructor(props){
super(props)
localStorage.removeItem("Token")
}
render(){
return(
<div>
<h2>You Have Been Logged Out</h2>
<Link to="/">Login</Link>
</div>
)
}
}
here is my GetStudentsByClass Component
class GetStudentsByClass extends Component {
constructor(props){
super(props)
let token = localStorage.getItem("Token")
let isloggedIn = true
if(token == null){
isloggedIn = false
}
this.state = {
isloggedIn
}
}
render(){
if(this.state.isloggedIn === false){
return <Redirect to="/"/>
}
return (
<div>
<h1> Get Student By Class</h1>
<Link to="/Logout">Logout</Link>
</div>
)
}
}
You can handle this issue either by aborting the request when your component unmounts or preventing this.setState() on an unmounted component.
You can call SubmitHandler() method inside ComponentDidMount() and remove
inside SubmitHandler(e) method. Ex.