繁体   English   中英

用于 API 调用的 React componentDidMount 与 useEffect 挂钩

[英]React componentDidMount vs useEffect hooks for API call

当我尝试使用 in useEffect 钩子(在组件挂载之前)进行 API 调用时,不知何故状态没有得到更新,因此我收到错误Cannot read property of undefined

但是,如果我将相同的逻辑转换为 Class 组件并在 componentDidMount 函数中进行 API 调用,则代码运行良好。

谁能告诉我为什么?

使用 useEffect

 import React from "react"; import axios from "axios"; import { useState, useEffect } from "react"; export default function Customers() { const [customers, setCustomers] = useState([]); useEffect(() => { axios .get("http://localhost:5000/customers") .then((res) => { const data = res.data; setCustomers(data); }) .catch((err) => console.log(err)); }, []); useEffect(() => { console.log(customers); }, [customers]); return ( <div className="container-fluid d-flex flex-column align-items-center justify-content-center"> <div className="top">Customers</div> <div className="tables"> <table class="table table-striped table-hover"> <thead> <tr> <th scope="col">Account No</th> <th scope="col">Name</th> <th scope="col">E-mail</th> <th scope="col">Balance</th> </tr> </thead> <tbody> {customers.data.map((customer) => ( // error on this line. <tr> <th scope="row">{customer.account_no}</th> <td>{customer.name}</td> <td>{customer.email}</td> <td>{customer.balance}</td> </tr> ))} </tbody> </table> </div> </div> ); }

基于类的组件

 import React, { Component } from "react"; import axios from "axios"; import "./Customers.css"; export default class Customers extends Component { state = { customers: [], }; componentDidMount() { axios .get("http://localhost:5000/customers") .then((res) => { res.data.sort(); console.log(res.data); this.setState({ customers: res.data }); }) .catch((err) => console.log(err)); } render() { return ( <div className="container-fluid main w-75 my-4 d-flex flex-column align-items-center"> <div className="top p-4 d-flex justify-content-center"> Our Customers </div> <div className="tables w-100"> <table class="table table-striped table-hover"> <thead> <tr> <th scope="col">Account No</th> <th scope="col">Name</th> <th scope="col">E-mail</th> <th scope="col">Balance</th> </tr> </thead> <tbody> {this.state.customers.map((customer) => ( <tr> <th scope="row">{customer.account_no}</th> <td>{customer.name}</td> <td>{customer.email}</td> <td>{customer.balance}</td> </tr> ))} </tbody> </table> </div> </div> ); } }

您没有在useEffect钩子中正确设置状态。 而不是setCustomers({data:data}); 它应该只是setCustomers(data);

useEffect(() => {
    axios
      .get("http://localhost:5000/customers")
      .then((res) => {
        const data = res.data;
        setCustomers(data);
      })
      .catch((err) => console.log(err));
  }, []);

现在因为customers是一个数组,只需映射customers而不是customers.data.map

customers.map((customer)=>{})

所以最终的代码将是

import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";

export default function Customers() {
  const [customers, setCustomers] = useState([]);

  useEffect(() => {
    axios
      .get("http://localhost:5000/customers")
      .then((res) => {
        const data = res.data;
        setCustomers(data);
      })
      .catch((err) => console.log(err));
  }, []);

  useEffect(() => {
    console.log(customers);
  }, [customers]);

  return (
    <div className="container-fluid d-flex flex-column align-items-center justify-content-center">
      <div className="top">Customers</div>
      <div className="tables">
        <table class="table table-striped table-hover">
          <thead>
            <tr>
              <th scope="col">Account No</th>
              <th scope="col">Name</th>
              <th scope="col">E-mail</th>
              <th scope="col">Balance</th>
            </tr>
          </thead>
          <tbody>
            {customers.map((customer) => ( 
              <tr>
                <th scope="row">{customer.account_no}</th>
                <td>{customer.name}</td>
                <td>{customer.email}</td>
                <td>{customer.balance}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

您将客户状态声明为数组:

const [customers, setCustomers] = useState([]);

但是您在获取数据后传递了一个对象:

 setCustomers({ data: data });

这就是 return 部分中的 map 迭代失败的原因,因为您将状态设置为对象而不是数组。 如果 data 是一个数组,你应该只像这样分配它:

setCustomers(data);

componentDidMount 工作是因为您将 res.data 直接分配给客户状态,结果类似于:

setCustomers(data);

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM