![](/img/trans.png)
[英]React Hooks API call - does it have to be inside 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.