当前位置: 首页 > 面试题库 >

无法在已卸载的组件上执行React状态更新?

齐威
2023-03-14
问题内容

我正在componentDidMount中获取数据并更新状态,并且出现了著名的警告:

无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。

state = {
    post: null
}

render() {
    console.log(this.props.postId)
    if (this.props.post) {
        return (
            <div>
                <h3> {this.state.post.postTitle} </h3>
                <p> {this.state.post.postBody} </p>
            </div>

        );
    } else {
        return <Redirect to="/blog" />
    }
}
componentDidMount() {
    this._isMounted = true;
    axios
        .get('https://jsonplaceholder.typicode.com/posts/' + + this.props.postId)
        .then((response) => {
            let post = {
                id: response.data.id,
                postTitle: response.data.title,
                postBody: response.data.body
            }
            this.setState((prevState,props)=>{
                console.log('post',post)
                console.log('prevState',prevState)
                console.log('props',props)
            })
        })
        .catch((e) => {
            console.log('error', e)
        })
}

}

是什么导致此警告,以及获取数据和更新状态的最佳方法是什么?


问题答案:

您的问题与以下问题相同。

如何开发组件,您可以进入循环并无限执行渲染。为了防止这种情况,请增加一种状态和控制,以使请求仅发出1次,或者仅在需要时发出“正念”请求。

另外,您的代码需要进行一些更改,您可以使用State来验证是否显示某些内容,并在发出请求后再次设置State。经过一些更改,您的代码可以如下所示:

state = {
    loadingData: true,
    post: null
}

render() {
    if (!this.state.loadingData) {
        return (
            <div>
                <h3> {this.state.post.postTitle} </h3>
                <p> {this.state.post.postBody} </p>
            </div>
        );
    } else {
        return <Redirect to="/blog" />
    }
}
componentDidMount() {
    this._isMounted = true;
    if(this.state.loadingData)
        axios
            .get('https://jsonplaceholder.typicode.com/posts/' + + this.props.postId)
            .then((response) => {
                this.setState({
                    loadingData: false,
                    post: {
                        id: response.data.id,
                        postTitle: response.data.title,
                        postBody: response.data.body
                    }
                })
        })
        .catch((e) => {
            console.log('error', e)
        })
}

我希望它有用。问候



 类似资料:
  • 问题内容: 我收到此错误: 无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。 当开始获取数据并卸载组件时,但是函数试图更新已卸载组件的状态。 解决此问题的最佳方法是什么? CodePen示例。 问题答案: 最简单的解决方案是使用局部变量来跟踪组件是否已安装。这是基于类的方法的常见模式。这是一

  • 我在React中编写一个应用程序,无法避免一个超级常见的陷阱,这是调用后。 我非常仔细地查看了我的代码,并试图将一些保护条款放在适当的位置,但问题仍然存在,我仍在遵守警告。 因此,我有两个问题: 如何从堆栈跟踪中找出哪一个特定组件和事件处理程序或生命周期挂钩导致了规则冲突? 好吧,如何解决问题本身,因为我的代码是在考虑这个陷阱的情况下编写的,并且已经在尝试防止它,但是一些底层组件仍然在生成警告 B

  • 我有一个React应用程序,其中来自父组件的道具被传递到子组件,然后道具设置子组件的状态。 如何让它更新子组件上的状态? 我的精简代码:

  • 我的Redux状态是如何更新的,可以在pokelist.js文件中注销,但是我的状态变量没有设置好,cardList还是一个空数组,我如何正确设置状态?我注销pokelist.js文件中的集合,它首先注销一个空数组,然后是一个包含元素的数组。

  • 问题内容: 我正在尝试学习如何实现React表单(ES6语法)并将每个字段的onChange事件传递到负责更新状态的控制器父组件。这对于标准html元素来说效果很好,但是我正在尝试对日期字段使用预先罐装的Datepicker(https://www.npmjs.com/package/react- bootstrap-date-picker ),并且无法随时通过事件以相同的方式备份到父级。有没有简

  • 我是个新来的土生土长的人。我有一个屏幕,它将根据其当前状态进行渲染,如下所示。默认情况下(初始状态),它将呈现登录屏幕。App.js 当下面的登录成功后,我需要将组件应用程序的状态从“初始”更改为“已登录”。我怎么做呢?这里的登录函数仅用于测试目的,所以不必太在意它。LoginBox.js