以编程方式调用钩子



https://codesandbox.io/s/react-hooks-usefetch-cniul

请参阅上面的网址,了解我的代码的简化版本。

我希望能够在一个时间间隔内用钩子从API重新获取数据(基本上是轮询端点以获取数据(。

我想要的是能够调用类似refetch的东西(正如我在代码中作为注释所示(,这实际上只是再次调用fetchData,并相应地用响应更新状态。

对此最好的方法是什么?我能想到的唯一方法是在钩子中添加一个checker变量,它可能是某种uuid(可能是Math.random()(,将setChecker作为refetch返回,然后将checker作为第二个useEffect参数添加到数组中以控制重新渲染。因此,每当您调用refetch时,它都会调用setChecker,它会更新随机数(checker(,然后函数会再次运行。

显然,这听起来很"古怪",一定有更好的方法——有什么想法吗?

如果您想进行持续的轮询,我认为您可以将setInterval()移动到挂钩中,如下所示:

function useFetch() {
const [data, setDataState] = useState(null);
const [loading, setLoadingState] = useState(true);
useEffect(() => {
function fetchData() {
setLoadingState(true);
fetch(url)
.then(j => j.json())
.then(data => {
setDataState(data);
setLoadingState(false);
});
}
const interval = setInterval(() => {
fetchData();
}, 5000);
fetchData();
return () => clearInterval(interval);
}, []);
return [
{
data,
loading
}
];
}

请记住包括return () => clearInterval(interval);,以便正确清理挂钩。

import React, { useEffect, useState, useCallback } from "react";
import ReactDOM from "react-dom";
const url = "https://api.etilbudsavis.dk/v2/dealerfront?country_id=DK";
function useFetch() {
const [data, setDataState] = useState(null);
const [loading, setLoadingState] = useState(true);
const refetch = useCallback(() => {
function fetchData() {
console.log("fetch");
setLoadingState(true);
fetch(url)
.then(j => j.json())
.then(data => {
setDataState(data);
setLoadingState(false);
});
}
fetchData();
}, []);
return [
{
data,
loading
},
refetch
// fetchData <- somehow return ability to call fetchData function...
];
}
function App() {
const [
{ data, loading },
refetch
// refetch
] = useFetch();
useEffect(() => {
const id = setInterval(() => {
// Use the refetch here...
refetch();
}, 5000);
return () => {
clearInterval(id);
};
}, [refetch]);
if (loading) return <h1>Loading</h1>;
return (
<>
<button onClick={refetch}>Refetch</button>
<code style={{ display: "block" }}>
<pre>{JSON.stringify(data[0], null, 2)}</pre>
</code>
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

也许下面的方法会奏效,它需要一些调整才能使用Fetch,但你仍然可以在其他地方正常调用它。

//maybe you can pass url as well so you can use
//  it with other components and urls
function useFetch(refresh) {
//code removed
useEffect(() => {
//code removed
}, [refresh]);
//code removed
}
const [refresh, setRefresh] = useState({});
const [{ data, loading }] = useFetch(refresh);
useEffect(() => {
const interval = setInterval(
() => setRefresh({}), //forces re render
5000
);
return () => clearInterval(interval); //clean up
});

问题的简单答案:

export default function App() {
const [entities, setEntities] = useState();
const [loading, setLoadingState] = useState(true);
const getEntities = () => {
setLoadingState(true);
//Changet the URL with your own
fetch("http://google.com", {
method: "GET",
})
.then((data) => data.json())
.then((resp) => {
setEntities(resp);
setLoadingState(false);
});
};
useEffect(() => {
const interval = setInterval(() => {
getEntities();
}, 5000);
return () => clearInterval(interval);
}, []);
}

相关内容

  • 没有找到相关文章

最新更新