Мне нужно создать запрос на опрос, но его нужно выполнять только тогда, когда пользователь нажимает активную кнопку, и каждые 5 секунд с момента нажатия, запрос будет выполняться до завершения статуса, я пытаюсь найти решение здесь, и лучшее решение было то, что я нашел в этой статье https://overreacted.io/making-setinterval-declarative-with-react-hooks/. Я сделал адаптацию, но она работает так, как я хочу.
Я хочу, чтобы setInterval вместо этого начинал работать только при нажатии кнопки, но я не знаю, как это сделать.
Это код
let times = 0;
export const request = id => {
if (times === 5) {
times = 0;
} else {
times++;
}
return new Promise(resolve =>
setTimeout(() => {
if (times === 5) {
resolve({
times,
status: "completed"
});
} else {
resolve({
times,
status: "in_progress"
});
}
}, 2000)
);
};
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
export default function App() {
const [isActive, setActive] = useState(false);
useInterval(async () => {
if (!isActive) return;
console.log("polling");
const { status, times } = await request();
console.log("times:", times);
if (status === "completed") {
setActive(false);
console.log("completed");
}
}, 1000 * 5);
return (
<div className="App">
<h1>Poll testing</h1>
<Button disabled={isActive} onClick={() => setActive(true)}>
{isActive ? (
<>
<Spinner
as="span"
animation="border"
size="sm"
role="status"
aria-hidden="true"
/>
</>
) : (
"Active"
)}
</Button>
</div>
);
}
. Вы можете запустить этот код на codeandbox: https://codesandbox.io/s/react-poll-hook-jxccy