【问题标题】:React JS - setState cannot be called on a component not yet mountedReact JS - 无法在尚未安装的组件上调用 setState
【发布时间】:2021-04-22 18:21:20
【问题描述】:

我在 React JS 中有我的应用程序。我正在从 http://localhost:8080/api/suppliers/supplier/list 的 API 获取数据:

这是我从 Google Chrome 控制台中的 REST API 获得的数据:

0:{
    id: 4
    supplierFirstname: "Tom"
    supplierLastName: "ABC"
    supplierTitle: "TomTheSupplier"
    accountNumber: 1122234444
    address: "111 ADrive, 1234 ST."
    companyName: "TheTom Company & Associates"
    email: "tomtomjayjay@email.com"
    hourlyRate: 29
    phoneNumber: 123456789
    otherPhoneNumber: 1023456789
    paymentTerms: "Credit"
    notes: "Some Supplier"
    createdAt: null
    typeOfGoods: "Supplies"
    website: "www.abc_123.com"
    products: [{…}]
    components: 
        [
            0: {id: 5, name: "AComponent", unit: null, quantity: 0, componentCost: 0, …}
        ]
    
}

这是我的 React 代码:

class SupplierData extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      supplier: [
        {
          id: 0,
          supplierTitle: "Supplier Title",
          supplierFirstName: "First Name",
          supplierLastName: "Last Name",
          companyName: "Company Name",
          phoneNumber: "Phone Number",
          otherPhoneNumber: "Phone Number (Other)",
          accountNumber: "Account Number",
          email: "Email",
          address: "Address",
          website: "Website",
          hourlyRate: "Hourly Rate",
          typeOfGoods: "Type Of Goods",
          paymentTerms: "Payment Terms",
          createdAt: "Created At",
          notes: "Notes",
          products: "Products",
          components: "Components",
        },
      ],
      errorMessage: [],
    };
    
  }

  listAllSuppliers = async () => {
    return await axios
      .get(`http://localhost:8080/api/suppliers/supplier/list`)
      .then((response) => {
        let apiResults = response.data;
        console.log(apiResults);
        this.setState({ supplier: apiResults });    <--- The error happens here.
      })
      .catch((error) => {
        this.setState({ errorMessage: this.state.errorMessage.push(error) });
      });
  };

  componentDidMount() {
    this.ListAllSuppliers();
  }
}

export default SupplierData;

我面临的问题是反应状态。我收到以下错误:

Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might 
         indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = 
         {};` class property with the desired state in the SupplierData component.

问题 1: (非常重要) 我要设置状态。

有什么办法可以解决上述错误?

问题 2: 这是在以下文件中调用上述类的正确方法吗? 我有以下代码:

    import SupplierData from './..';



    export const A = (props) =>{
    const {id, supplierTitle, supplierFirstName, supplierLastName, 
           companyName, phoneNumber, otherPhoneNumber, accountNumber, email, 
           address, website, hourlyRate, typeOfGoods, paymentTerms, 
           createdAt, notes, products, components, status } = props;


       let mySupplier = new SupplierData();
       let listData = mySupplier.listAllSuppliers();


       return(
        <tr>
            <td>
                <Card.Link as={Link} to={Routes.Suppliers.path} className="fw-normal">
                   {SupplierData.map((t, id) => <tr key={id}> {t.fetchedData} </tr>)}  <--- Here is where the error is
                </Card.Link>
            </td>
         </tr>
       );
    }
}

【问题讨论】:

    标签: javascript node.js reactjs axios


    【解决方案1】:

    解决问题 2 是解决问题 1 的方法,所以我将回答问题 2:

    不,这绝对不是调用 React 组件的正确方式。

    SupplierData 是一个 React 组件,并且由于您已经拥有调用 listAllSuppliers()componentDidMount() 生命周期方法,您需要做的就是挂载一个 SupplierData 组件:

    import SupplierData from "./..";
    
    export const A = (props) => {
      return (
        <tr>
          <td>
            <Card.Link as={Link} to={Routes.Suppliers.path} className="fw-normal">
              <SupplierData />
            </Card.Link>
          </td>
        </tr>
      );
    };
    

    基于 cmets 编辑

    可能想要在这里实现的一个非常简单的重新表述如下。

    由于您的 API 结果示例清楚地描述了一个包含对象的对象,并且您的代码似乎假定为一个数组,因此我不知道什么是真正正确的。因此,渲染代码只是转储加载的数据。

    此外,缺少错误处理。

    const SupplierData = () => {
      const [supplier, setSupplier] = React.useState(null);
      React.useEffect(() => {
        axios
          .get(`http://localhost:8080/api/suppliers/supplier/list`)
          .then((response) => setSupplier(response.data))
          .catch(alert);
      }, []);
      if (supplier === null) return <>Loading...</>;
      // TODO: implement better rendering code
      return <>{JSON.stringify(supplier)}</>;
    };
    
    export const A = (props) => {
      return (
        <>
          Hello, world!
          <SupplierData />
        </>
      );
    };
    

    【讨论】:

    • 我已经在我的问题中特别添加了错误所在。请检查并告诉我您的建议。感谢您的时间。
    • 不幸的是,您似乎误解了 React 组件及其本地状态的工作方式。您需要在具有状态的组件中映射该数据 - 将渲染方法添加到 SupplierData...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多