javascript - React Js Error Can't perform a React state update on an unmounted component
问题描述
我正在处理登录注销组件,一切正常,但有时会弹出此错误Can't perform a React state update on an unmounted component。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务,我在 Internet 上搜索并尝试了许多解决方案,但没有什么对我有用
这是我的登录组件
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="clark@dashboard.com"></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>
)
}
}
这是我的注销组件
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>
)
}
}
这是我的 GetStudentsByClass 组件
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>
)
}
}
解决方案
您可以通过在组件卸载时中止请求或阻止 this.setState() 在卸载的组件上来处理此问题。
您可以在 ComponentDidMount() 中调用 SubmitHandler() 方法并删除
this._isMounted = true;
在 SubmitHandler(e) 方法中。前任。
componentDidMount(){
this._isMounted = true;
this.onClickSubmitHandler();
}
onClickSubmitHandler() {
SubmitHandler = (e) => {
e.preventDefault();
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)
}
})
}
}
推荐阅读
- openapi - 将项目作为项目中的模块移动后,打开 api swagger-ui 给出白标错误页面(404)
- python - Gekko 最优控制。如何创建多个终止目标/条件?
- javascript - 短路代替三元运算符
- haskell - 如何映射带有两个参数(而不是一个)的函数?
- nginx - Nginx 不使用返回指令请求身份验证子请求
- azure - REDIRECT_URI_MISMATCH 与 Azure AD B2C Web 应用程序(基于 Python/Flask)
- python - 我想将输出值放在数据框的列中
- visual-studio-code - Visual Studio Code 文本选择
- maven-surefire-plugin - Maven配置文件从包中排除junit不起作用
- python - 结合几个隐马尔可夫模型