What is the sequence of actions when using promises in useEffect hook in React?

浪子不回头ぞ 提交于 2020-12-26 11:10:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!