【问题标题】:React Js Error Can't perform a React state update on an unmounted componentReact Js Error Can't perform a React state update on an unmounted component
【发布时间】:2020-05-15 17:38:35
【问题描述】:

我正在处理登录注销组件,一切正常,但有时会弹出此错误 无法在未安装的组件上执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务我在互联网上搜索并尝试了许多解决方案,但没有任何工作适合我

这是我的登录组件

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>

    )

}

}

【问题讨论】:

  • 您希望在按下按钮时提交表单吗?如果没有,只需删除 &lt;form&gt; 元素或阻止它被提交。
  • 是的,我想提交表格
  • 我已经删除了表格,但问题仍然存在@tit
  • 没关系,我看到您在按下按钮时调用的SubmitHandler 函数中有一个e.preventDefault() 调用。
  • 我添加了这个,因为我不知道当我按下按钮时我的页面会自行刷新,即使提交处理程序中没有代码

标签: javascript reactjs react-router


【解决方案1】:

您可以通过在组件卸载时中止请求或阻止 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)

        }

    })
}
}

【讨论】:

  • 如何在 componentdidmount 中调用 submithandler 先生,我是新来的反应 js
  • 现在我收到此错误“无法读取未定义的属性 'preventDefault'”
  • 您需要在括号中传递事件。请检查我的更新答案。
  • e 没有定义我应该在哪里定义这个 e
  • 问题还是一样我已经从提交处理程序中删除了 e.preventDefault 并从 jsx 中删除了表单标签问题仍然相同
猜你喜欢
  • 2019-10-29
  • 2020-01-15
  • 2021-05-05
  • 2021-03-25
  • 2022-01-11
  • 2022-06-10
  • 2022-06-10
  • 2020-06-28
  • 2020-09-10
相关资源
最近更新 更多