在下面的代码中,我预计在useEffect钩子console.log过程中会记录getAllTickets函数获取的票证列表,因为票证列表会返回而不会出错。然而,console.log会记录一个空数组,该数组是我最初在状态中设置的。console.log似乎在获取过程之前,并在setTickets挂钩之后。有人能帮助澄清这种困惑吗?
import ReactDOM from 'react-dom';
import * as React from 'react';
import { getAllTickets } from './api';
const App = () => {
const [tickets, setTickets] = React.useState([]);
React.useEffect(() => {
getAllTickets()
.then((res) => setTickets([...res]))
.then(() => console.log(tickets))
.catch((e) => console.log(e));
}, []);
const renderTickets = tickets.map((t) => (
<div key={t.id}>
<p>{t.description}</p>
</div>
));
return (
<div>
{renderTickets}
<button onClick={() => setOpen(true)}>Add ticket</button>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
getAllTickets从数据库获取票证列表,如下所示
export const getAllTickets = async () => {
const res = await fetch('http://localhost:3001/tickets');
const data = await res.json();
console.log(data);
return data;
};
这并不是说存在排序问题。记录tickets
值的函数就是记录一个旧值。
每次调用组件函数时都会创建useEffect
回调,但由于依赖数组为空,因此useEffect
只调用这些函数中的第一个。第一个函数关闭了对创建回调的组件函数(第一个调用(的调用的tickets
常量,其中tickets
是一个空数组。因此,尽管setTickets
更新了您的状态项,这将导致您的组件函数再次被调用,但useEffect
回调(或者更准确地说,它创建的回调(将继续使用旧值。
如果您想查看更新后的阵列,可以使用res
:
React.useEffect(() => {
getAllTickets()
.then((res) => {
const ticketsReceived = [...res]; // Why the shallow copy?
setTickets(ticketsReceived);
console.log(ticketsReceived);
})
.catch((e) => console.log(e));
}, []);