【问题标题】:Which one is executed first Fetch or setState?Fetch 和 setState 哪个先执行?
【发布时间】:2021-07-24 08:10:48
【问题描述】:

我试图从 HTML 表单将数据从前端(React)发送到后端(快递),并在提交后清除字段。这就是它的样子。这里 item 和 amount 是受控组件的状态。所以我的问题是我在获取它之前更新状态而不更新它。由于 fetch 和 setState 是异步的,因此哪个将首先执行。即使我在 fetch 之后写入状态更新,似乎 fetch 也是首先执行的。但我不知道怎么做?

function onSub(e, setList, list) {
e.preventDefault();


setList([...list, { item, amount }]);
setItem("");
setAmt("");


  fetch("http://localhost:3001/addData", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ title: item, amt: amount }),
  })
    .then((res) => res.text())
    .then((data) => {
      console.log(data);
    });

}

【问题讨论】:

  • 你为什么在乎?从您显示的代码来看,这两者无论如何都是相互独立的。

标签: javascript reactjs setstate


【解决方案1】:

他们正在比赛中。通常,您希望首先设置状态,因为状态设置器仅在 DOM 内本地运行,fetch 必须与服务器通信,但它们正在竞争,您不能指望哪一个会赢得比赛。

如果你想控制哪个先发生,你需要明确地做到这一点。让fetch 先完成更容易,因为您可以等到fetch 进程结束后再调用状态设置器。这也让您有机会处理 fetch 故障(例如,瞬时网络错误)而不会丢失用户提供的信息,因为您已经将其从状态中清除:

function onSub(e, setList, list) {
    e.preventDefault();

    fetch("http://localhost:3001/addData", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({ title: item, amt: amount }),
    })
    .then((res) => {
        if (!res.ok) { // This check was missing
            throw new Error(`HTTP error ${res.status}`);
        }
        return res.text();
    })
    .then((data) => {
        console.log(data);
        setList([...list, { item, amount }]);
        setItem("");
        setAmt("");
    })
    .catch(error => {
        setError(/*...some error message saying something went wrong...*/);
    });
}

旁注:我解释了有关缺少here 的支票的评论。为了避免编写所有样板文件,我建议使用一些方便的实用程序函数,例如:

export async function postJSON(url, data) {
    const res = await fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
    });
    if (!res.ok) { // This check was missing
        throw new Error(`HTTP error ${res.status}`);
    }
    return res;
}

那么代码将如下所示:

function onSub(e, setList, list) {
    e.preventDefault();

    postJSON("http://localhost:3001/addData", { title: item, amt: amount })
    .then((data) => {
        console.log(data);
        setList([...list, { item, amount }]);
        setItem("");
        setAmt("");
    })
    .catch(error => {
        setError(/*...some error message saying something went wrong...*/);
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2019-09-03
    • 2013-08-14
    • 2013-10-27
    • 1970-01-01
    相关资源
    最近更新 更多