【问题标题】:How to fetch from another API after useState has finished setting the valueuseState 完成设置值后如何从另一个 API 获取
【发布时间】:2022-01-13 23:00:53
【问题描述】:

我正在提交表单并获取 2 个 API。第一个 API 给了我一个令牌值,然后我需要它作为第二个 API 的数据。我将令牌放入const[token, setToken] = useState();

收到令牌后,我使用setToken 来存储令牌。现在我希望这个令牌用于我的下一个 API 调用。但setToken 在第二个 API 调用中未定义。

我都这样称呼:

    axios
      .request(options)
      .then(function (response) {
        console.log(response.data.id);
        setToken(response.data.id)
      })
      .then(function(response) {
        saveCard();
      })
      .catch(function (error) {
        console.error(error);
      });

saveCard() 是我调用第二个 API 的地方,它使用我之前设置的 token。在设置令牌之前,它正在调用saveCard() 函数。令牌完全设置后如何调用saveCard()函数。

【问题讨论】:

  • 这能回答你的问题吗? How to use callback with useState hook in react
  • 我将尝试自定义钩子解决方案,因为 useEffect 在我的情况下不起作用。是需要token的表单提交。
  • 我不明白为什么你不能添加一个依赖于tokenuseEffect 钩子来执行你的第二个请求
  • 当然,我可以在 useEffect 中执行它,并将 token 作为依赖项,但在我的情况下,它必须在表单提交上完成。只有当我收到表单中的某些值以及token 时,我才必须执行第二个 API 调用,然后我必须提交表单。
  • 对不起,我没有意识到这是为了提交表单。我将撤回对副本的投票。您能否编辑您的原始问题以表明在提交表单时执行此代码?

标签: reactjs axios


【解决方案1】:

有几种方法可以解决这个问题,其中最简单的可能是将令牌从第一个请求传递到 saveCard 方法 -

axios
    .request(options)
    .then(function (response) {
        console.log(response.data.id);
        setToken(response.data.id)

        // This gets passed to the next function in the chain
        return response.data.id;
    })
    .then(function(token) {
        saveCard(token);
    })
    .catch(function (error) {
        console.error(error);
    });

实际上 - 您不需要将 saveCard 隔离到单独的 then 回调中 -

axios
    .request(options)
    .then(function ({ data }) {
        const token = data.id;

        setToken(token);
        saveCard(token);
    })
    .catch(function (error) {
        console.error(error);
    });

但是,如果您真的想使用来自setState 调用的令牌调用saveCard 方法,您将不得不使用useEffect。你可以这样做:

// Presuming you have something that represents your form state
const [formData, setFormData] = useState({});

const [token, setToken] = useState("");
const [submitting, setSubmitting] = useState(false);

const handleSubmit = async () => {
    if (submitting) return;

    setSubmitting(true);

    try {
        const { data } = await axios.request(options);
        setToken(data.id);

    } catch (error) {
        console.error(error);
        setSubmitting(false);
    }
};

useEffect(() => {
    // We can only call 'save' if we are in "submitting" mode, 
    // and we have a token.
    if (!(submitting && token)) return;

    saveData();

    // You'd probably have to reset your token here too presuming
    // you need to fetch another one again when you save.
    setToken("");
    setSubmitting(false);

}, [submitting, token, formData]

如您所见,这要尴尬得多;所以我想你必须问自己,你真的需要令牌作为状态吗?最干净的解决方案是完全删除它,并使用 async/await 而不是承诺:

try {
    // Get the token
    const { data } = await axios.request(options);
    const { id: token } = data;

    // Now use the token to submit the form - I'm presuming this is async too?
    await saveCard(token);

} catch (error) {
    console.error(error);
}

【讨论】:

  • 非常感谢!非常详细的答案,让我探索了许多我没有想到的其他可能性:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多