Javascript 在React中使用Useffect钩子中的承诺时,操作的顺序是什么?

Javascript 在React中使用Useffect钩子中的承诺时,操作的顺序是什么?,javascript,reactjs,asynchronous,fetch,Javascript,Reactjs,Asynchronous,Fetch,在下面的代码中,我希望useffect hook console.log过程将记录getAllTickets函数获取的票证列表,因为票证列表返回时没有错误。但是console.log会记录我在初始状态下设置的空数组。似乎console.log在某种程度上位于fetch进程之前,而在setTickets钩子之后。有人能帮忙澄清这一困惑吗 import ReactDOM from 'react-dom'; import * as React from 'react'; import { getAl

在下面的代码中,我希望useffect hook console.log过程将记录getAllTickets函数获取的票证列表,因为票证列表返回时没有错误。但是console.log会记录我在初始状态下设置的空数组。似乎console.log在某种程度上位于fetch进程之前,而在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'));

并不是说有顺序问题。记录
tickets
值的函数记录的是一个旧值

每次调用组件函数时都会创建
useffect
回调,但由于依赖项数组为空,因此
useffect
只调用这些函数中的第一个。对于创建回调(第一次调用)的组件函数的调用,第一个函数关闭
tickets
常量,其中
tickets
是一个空数组。因此,尽管
setTickets
更新了状态项,这将导致再次调用组件函数,但是
useffect
回调(或者更准确地说,它创建的回调)仍然使用旧值

如果要查看更新的阵列,可以使用
res

React.useEffect(() => {
  getAllTickets()
    .then((res) => {
          const ticketsReceived = [...res]; // Why the shallow copy?
          setTickets(ticketsReceived);
          console.log(ticketsReceived);
     })
    .catch((e) => console.log(e));
}, []);

谢谢TJ的解释。关于浅拷贝,老实说,我没有任何有意义的理由使用浅拷贝而不是浅拷贝,我只是认为这是设定状态下的模式。每次我遇到闭包,我都会做大量的研究,认为我最终理解了一切,直到下一次我再次遇到闭包,才发现我没有理解它properly@esentai我们都去过那里@esentai我创建这个沙盒只是为了更深入的了解,请检查控制台
React.useEffect(() => {
  getAllTickets()
    .then((res) => {
          const ticketsReceived = [...res]; // Why the shallow copy?
          setTickets(ticketsReceived);
          console.log(ticketsReceived);
     })
    .catch((e) => console.log(e));
}, []);