简体   繁体   English

无法使用componentDidMount从API提取数据:无法在已卸载的组件上调用setState(或forceUpdate)

[英]Cannot fetch data from an API using componentDidMount: Can't call setState (or forceUpdate) on an unmounted component

I'm relatively new to React. 我是React的新手。 I've used it for building a very simple app. 我用它来构建一个非常简单的应用程序。 I'm trying to add a small feature, but running into following error message. 我正在尝试添加一个小功能,但遇到以下错误消息。 I don't quite understand the root cause yet. 我还不太了解根本原因。

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.

Here's what I'm trying to do. 这就是我想要做的。 My app has a backend server that provides various APIs, which returns JSON. 我的应用程序有一个提供各种API的后端服务器,该API返回JSON。 I'm using React as frontend/client that calls those APIs and renders them. 我正在使用React作为调用这些API并呈现它们的前端/客户端。

I have a Parent component named MyReport which uses componentDidMount to call an API to fetch some data. 我有一个名为MyReport的父组件MyReportcomponentDidMount使用componentDidMount来调用API来获取一些数据。 Then in the render method, I pass the data to another component named MyReportViewer . 然后在render方法中,将数据传递到另一个名为MyReportViewer组件。 This component has various other child components such as a Calendar that allows selecting date, a component that shows the data in a table format, a component that shows the same data as a chart. 该组件具有各种其他子组件,例如允许选择日期的日历,以表格格式显示数据的组件,与图表显示相同数据的组件。

Now I'm trying to add another child component called MyReportSummary that will be displayed alongside the other components rendered by MyReportViewer . 现在,我试图添加另一个名为MyReportSummary子组件,该子组件将与MyReportViewer呈现的其他组件一起显示。

MyReportSummary needs to call another API to fetch some data. MyReportSummary需要调用另一个API来获取一些数据。 This is what it looks like: 看起来是这样的:

import React, { Component } from 'react';

class MyReportSummary extends Component {

    constructor(props) {
        super(props);
        this.state = {
            projectInfo: null,
            isLoading: false,
            error: null
        };
    }

    componentDidMount() {
        this.setState({ isLoading: true });

        let projectInfoApi;

        projectInfoApi = '/api/projects/' + this.props.projectId;

        fetch(projectInfoApi)
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error('Encountered problem fetching project info')
                }
            })
            .then(data => this.setState({
                projectInfo: data
            }))
            .catch(fetchError => this.setState({
                isLoading: false,
                error: fetchError
            }));
    }

    componentWillUnmount() {
        // this.setState({
        //     projectInfo: null
        // });
    }

    render() {
        const { isLoading, error } = this.state;

        if (error) {
            return <p>{error.message}</p>
        }

        if (isLoading) {
            return <p>Loading...</p>
        }

        return (
            <div className="myReportSummary">
                 Summary of Project name: {projectInfo.name}                    
                 Number of events: {this.props.data.length}
            </div>
        );
  }
}

export default MyReportSummary;

I've read that I need to use componentWillUnmount to reset everything, but I'm not sure what exactly I need to reset here and why in this case I need to do it because I don't think I'm trying to change the component after it's been loaded or rendered already. 我已经读到我需要使用componentWillUnmount来重置所有内容,但是我不确定在这里究竟需要重置什么,以及为什么在这种情况下需要这么做,因为我不认为我想更改组件已经加载或呈现后。

The warning indicates that your component has been unmounted before you get a chance to handle the response of your fetch. 该警告表明您有机会处理获取的响应之前已卸载组件。

You can keep a property on your component outside of state called eg isMounted and set that to false in componentWillUnmount and check if it's true when your fetch has completed: 您可以将组件的属性保留在状态之外,例如isMounted并在componentWillUnmount isMounted其设置为false ,并在获取完成后检查它是否为true

Example

class MyReportSummary extends Component {
  mounted = true;
  state = {
    projectInfo: null,
    isLoading: true,
    error: null
  };

  componentDidMount() {
    fetch(`/api/projects/${this.props.projectId}`)
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          throw new Error("Encountered problem fetching project info");
        }
      })
      .then(data => {
        if (this.mounted) {
          this.setState({
            projectInfo: data
          });
        }
      })
      .catch(fetchError => {
        if (this.mounted) {
          this.setState({
            isLoading: false,
            error: fetchError
          });
        }
      });
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  render() {
    const { isLoading, error, projectInfo } = this.state;

    if (error) {
      return <p>{error.message}</p>;
    }

    if (isLoading) {
      return <p>Loading...</p>;
    }

    return (
      <div className="myReportSummary">
        Summary of Project name: {projectInfo.name}
        Number of events: {this.props.data.length}
      </div>
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法在卸载的组件上调用setState(或forceUpdate) - Can't call setState (or forceUpdate) on an unmounted component 反应警告:无法在未安装的组件上调用 setState(或 forceUpdate) - React Warning: Can't call setState (or forceUpdate) on an unmounted component 警告:无法在React Native中的已卸载组件上调用setState(或forceUpdate) - Warning: Can't call setState (or forceUpdate) on an unmounted component in React Native 警告:无法在卸载的组件上调用setState(或forceUpdate) - Warning: Can't call setState (or forceUpdate) on an unmounted component 反应-警告:无法在未安装的组件上调用setState(或forceUpdate) - React - Warning: Can't call setState (or forceUpdate) on an unmounted component 无法在已卸载的组件上调用setState(或forceUpdate)。 应对 - Can't call setState (or forceUpdate) on an unmounted component. React 即使在componentDidMount之后,也无法在已卸载的组件上调用setState - Can't Call setState on an unmounted component even after componentDidMount 如何解决:无法在 React-Native 中的未挂载组件警告上调用 setState(或 forceUpdate)? - How to solve: Can't call setState(or forceUpdate) on an unmounted component warning in React-Native? 无法在已卸载的组件上调用setState(或forceUpdate)。 react-image-gallery上的内存泄漏 - Can't call setState (or forceUpdate) on an unmounted component. Memory leak on react-image-gallery 有人知道如何解决此错误:无法在已卸载的组件上调用setState(或forceUpdate)吗? - Does somebody know how to fix this error: Can't call setState (or forceUpdate) on an unmounted component…?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM