问题
In the code below I was expecting that inside the useEffect hook console.log procedure will log the list of the tickets fetched by getAllTickets function because list of the tickets is returned without error.However console.log results in logging an empty array that I set up in the state initially. It seems that console.log is somehow preceding the fetch process and following setTickets hook. Could someone help to clarify this confusion?
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 fetches list of tickets from db as below
export const getAllTickets = async () => {
const res = await fetch('http://localhost:3001/tickets');
const data = await res.json();
console.log(data);
return data;
};
回答1:
It's not that there's a sequencing issue. It's that the function logging the tickets
value is logging an old value.
Your useEffect
callback is created each time your component function is called, but because your dependency array is empty, only the first of those functions is ever called by useEffect
. That first function closes over the tickets
constant for the call to your component function that created the callback (the first call), in which tickets
is an empty array. So although setTickets
updates your state item, which will cause your component function to be called again, your useEffect
callback (or more accurately, the callbacks it creates) continue to use the old value.
If you want to see the updated array, you can use res
:
React.useEffect(() => {
getAllTickets()
.then((res) => {
const ticketsReceived = [...res]; // Why the shallow copy?
setTickets(ticketsReceived);
console.log(ticketsReceived);
})
.catch((e) => console.log(e));
}, []);
来源:https://stackoverflow.com/questions/65409183/what-is-the-sequence-of-actions-when-using-promises-in-useeffect-hook-in-react