reactjs - 用于 API 调用的 React componentDidMount 与 useEffect 挂钩
问题描述
当我尝试使用 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>
);
}
推荐阅读
- android-studio - 广告无法在 android studio 中加载
- node.js - Mongoose 在没有 ref 的情况下查找其他集合
- javascript - 运行 mocha 测试无法从绝对路径中找到模块
- ios - 上一个任务结束后是否可以再次启动BackgroundTask
- regex - 带有正则表达式的 Spring Boot 中的 URL 匹配器
- java - 如何停止版本垃圾收集
- windows - 在带有巧克力的 Windows 10 Pro 上安装软件包时出现问题,我无法在我的 PC 上的任何地方找到已安装的软件包
- android - 如何使用 ScrollView 和 Linear Layout 仅使部分布局可滚动?
- javascript - 如何删除JS数组中的下一个相等元素
- mysql - MySQL 自连接优化,同时计算移动平均值