Создание setInterval для реакции с использованием хуков с условным - PullRequest
0 голосов
/ 17 января 2020

Мне нужно создать запрос на опрос, но его нужно выполнять только тогда, когда пользователь нажимает активную кнопку, и каждые 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

...