【问题标题】:How to fetch API and store some value and then fetch again with that stored value in React如何获取 API 并存储一些值,然后在 React 中使用存储的值再次获取
【发布时间】:2021-10-05 01:43:00
【问题描述】:

目前我正在获取一些数据并通过useState 保存响应。响应已保存,但问题是在保存状态之前进行第二次获取,使该值变为undefined

我试着这样做:

  useEffect(() => {
    fetchTrackingData().finally(() => {
      console.log("Destination", destination.coordinates);
      fetchDriverLocation().finally(() => {
        setLoading(false);
      });
    });
  }, []);

基本上fetchTrackingData 函数具有我保存的目标坐标:

const [destination, setDestination] = useState('');

fetchTrackingData 函数中,我在收到响应后设置状态。在fetchTrackingData 完成获取并保存destination 的状态后,我使用finally() 方法,然后调用第二个获取fetchDriverLocation 但它有destination 未定义,甚至我登录查看该值是否在finally() 之后保存,但日志中也是undefined

如何将来自一个 API 的值存储在该 API 调用中,然后在另一个 API 调用中使用该值?

【问题讨论】:

  • 您确定fetchTrackingData 返回数据并按预期设置数据吗?即使是这样,setDestination 也会异步运行,因此您不能确定它在调用 fetchDriverLocation 之前运行。我认为您将需要重新考虑如何实现此逻辑。不幸的是,我不确定到底是怎么回事,但是在 stackoverflow 上进行一些搜索可能有助于找到正确的模式。
  • 是的,它返回数据,我可以记录该数据并设置数据,因为我在其他地方使用了其中一个设置值,它会显示出来。
  • 那么我认为这是 setDestination 的异步特性。没有立即设置目标,导致错误(奇怪的是,当您将默认设置为 '' 时,它是未定义的)。你能显示fetchTrackingData的代码吗?
  • 发生这种情况是因为我正在利用 destination.coordinates 但如果我只是 console.log destination 它不会显示未定义

标签: reactjs axios


【解决方案1】:

正如另一个answer 所说,您正在经历竞争条件,因为反应中的setState 通常是asynchronous

我的建议是使用两个useEffects 来完成此操作:

useEffect(() => {
  fetchTrackingData();
}, []);

useEffect(() => {
  console.log("Destination", destination.coordinates);
  fetchDriverLocation().finally(() => {
    setLoading(false);
  });
}, [destination]);

上述内容将等到destination 发生更改,然后再继续获取驱动程序位置

【讨论】:

  • 这个答案也是个好建议!
  • 谢谢我能够通过这个方法完成我想要的事情
【解决方案2】:

您遇到的是一种竞争条件。

当您调用fetchTrackingData 时,它会向您的API 发出HTTP 请求,获得响应,然后它所做的最后一件事就是将destination 保存到state。但是当你调用setDestination时,这是另一个被启动的异步任务,然后你直接尝试从状态中访问它(它可能存在也可能不存在,取决于设置状态需要多长时间)。

我的建议是要么不依赖状态进行此过程(也许一个变量会这样做?或者甚至只是传递你的 http 请求的结果)或者更依赖于链接这些Promises 并将状态设置包含在 Promise 链中。但是,我赞成前一个建议

见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

和:Chain React setState callbacks

【讨论】:

    【解决方案3】:

    您可以尝试使用 async await 方法,并在第一个 API 完成后调用其他 API。

    例子:

    function App() {
      const [data, setData] = useState();
      const [data2, setData2] = useState();
    
      useEffect(() => {
        (async () => {
          const response = await fetch("someURL");
          const json = await response.json();
          setData(json);
          const responseList = await fetch("someURL" + json.data);
          const jsonData = await responseList.json();
          setData2(jsonData)
        })();
      }, []);
    
    
      return (
        <div>
            Hello
        </div>
      );
    }
    
    export default App;
    

    【讨论】:

    • 使用 async/await 等同于 OP 所做的。它不会解决问题,因为 setState 是异步的
    【解决方案4】:

    通过使用 useEffect 获取数据从 firstURI 并发送 到 secondURI

      const [firstDate, setFirstData] = useState();
      const [secondDate, setSecondData] = useState();
    
      useEffect(() => {
        (async () => {
          const firstResponse = await fetch("firstURI");
          const firstResponseData = await firstResponse.json();
          setFirstData(firstResponseData);
          
          const secondResponse = await fetch("secondURI" + firstResponseData.data);
          const secondResponseData = await secondResponse.json();
          setSecondData(secondResponseData)
        })();
      }, []);
    

    【讨论】:

    • 这并没有给出解决方案,因为它等同于 OP 所做的。问题在于setState 没有等待承诺解决
    猜你喜欢
    • 2021-02-11
    • 2020-03-31
    • 2021-04-28
    • 1970-01-01
    • 2021-10-21
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多