反应钩子,直到上一次调用完成

时间:2019-06-20 02:41:37

标签: reactjs redux react-hooks

我正在使用钩子的React项目。我被分配了一个任务

”更改useInterval钩子,或创建一个新的钩子(usePoll?)。此操作应与useInterval相同,但应等待ajax请求完成后再开始计时器”。

我是新来反应钩子的人,我一直在寻找解决方案,但找不到。当前的useInterval函数如下。

import React, { useEffect, useRef } from 'react';

export function useInterval(callback, delay, immediate = true) {
    const savedCallback = useRef();

    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);

    // Set up the interval.
    useEffect(() => {
        function tick() {
            savedCallback.current();
        }
        if (delay !== null) {
            if (immediate) {
                tick();
            }

            let id = setInterval(tick, delay);
            return () => clearInterval(id);
        }
    }, [delay]);
}

,它在程序中的用法如下。

useInterval(() => {
        get(`/api/v1/streams/1`).then(({ data: { data } }) => {
            setStream(data);
        });
    }, 5000);

,我需要更改useInterval函数,以等到ajax请求完成后再启动计时器。如果有人可以在这方面帮助我,那将是很棒的。谢谢

2 个答案:

答案 0 :(得分:0)

试一下。.它需要调用toRemove[0]内部的next函数,但它应该与您要查找的内容接近。

then

用法:

function useInterval(handler, delay, immediate = true) {
  React.useEffect(() => {
    let interval

    const start = () => {
      clearInterval(interval)
      interval = setInterval(() => handler(start), delay)
    }

    handler(start)

    return () => clearInterval(interval)
  }, [])
}

答案 1 :(得分:0)

您可以使用async\await等待首次通话完成。

像这样修改内部useEffect

export function useInterval(callback, delay, immediate = true) {
    const savedCallback = useRef();

    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);
    // Set up the interval.
    useEffect(() => {
        // useEffect doesn't like async callbacks (https://github.com/facebook/react/issues/14326) so create nested async callback
        (async () => { 
            // Make tick() async
            async function tick() {
                await savedCallback.current();
            }
            if (delay !== null) {
                if (immediate) {
                    await tick();  // Here we should await for tick()
                }

                let id = setInterval(tick, delay);  // Unfortunately setInterval is not async/await compatible. So it will not await for tick
                return () => clearInterval(id);
           }
        })(); // Call nested async function
    }, [delay]);

}

您的回调应该返回Promise,以便async\await正常工作

useInterval(() => {
    // After .then promise will be resolved, so our useInterval will know about that
    return get(`/api/v1/streams/1`).then(({ data: { data } }) => {
        setStream(data);
    });
}, 5000);