使用用户输入更新 useEffect api 调用 url

Updating useEffect api call url with user inputs

我正在做一个项目,我需要用用户输入的日期更新数据图表。我在如何更新 useEffect 挂钩内的 url 时遇到了问题。这是我的相关代码:

const finalUrl =`${apiUrl}id=${id}&timing=${time}&start=${finalStart}&end=${finalEnd}`;
    console.log(finalUrl);

useEffect(() => {
    
    axios
      .get<AxiosResponse>(finalUrl, {
        headers: {
          "Content-Type": "application/json"
        }
      })
      .then(response => {
        setData(response);
      })
      .catch(error => {
        console.log(error);
      });
  }, []);
  console.log(data); 

在我进行 axios 调用之前,一切看起来都很好。我无法让 useEffect 使用更新后的 url。每次记录响应数据都会给出相同的结果。 “finalUrl”中的所有值均来自用户。

我假设 apiUrlid 永远不会改变,但是你在 API URL 中使用的所有其他东西都是输入来自用户。

如果是这样,您需要在 useEffect 回调中重建 URL,并使回调依赖于这些用户输入,如下所示:

useEffect(() => {
    const finalUrl =`${apiUrl}id=${id}&timing=${time}&start=${finalStart}&end=${finalEnd}`;
    axios
        .get<AxiosResponse>(finalUrl, {
            headers: {
                "Content-Type": "application/json"
            }
        })
        .then(response => {
            setData(response);
        })
        .catch(error => {
            console.log(error);
        });
}, [time, finalStart, finalEnd]);

timefinalStartfinalEnd发生变化时回调将被再次调用。


请注意,当依赖关系发生变化时,您还需要忽略或取消之前的请求,即使请求尚未完成。我不使用 axios,但据我了解,它有一个“cancel/cancellation 令牌”,您可以使用它来执行此操作。这是 fetch 的样子,它使用 AbortController:

useEffect(() => {
    const finalUrl =`${apiUrl}id=${id}&timing=${time}&start=${finalStart}&end=${finalEnd}`;
    // Create the controller so we can cancel the request
    const controller = new AbortControlller();
    // Pass `signal` to fetch vvvvvvvvvvvvvvvvvvvvvvvvvvv
    fetch<DataType>(finalUrl, {signal: controller.signal})
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error ${response.status}`);
            }
            return response.json();
        })
        .then(setData)
        .catch(error => {
            console.log(error);
        });
    // Return a cleanup callback
    return () => {
        // Cancel the request since its response would be out of date
        controller.abrt();
    };
}, [time, finalStart, finalEnd]);
console.log(data);