反应超时和清除超时

时间:2019-07-24 23:59:24

标签: reactjs settimeout use-effect

我有一个React页面,该页面未设置为组件。我希望使用useEffect之类的React Hooks或任何其他建议。基本上,我需要清除超时。

const ExamplePage = ({
  test1, test2, test3
}: Props) => {
  const setClipboardTimer = (index, copied, show, delay) => {
    const timer = setTimeout(() => {
      setClipboardData(index, copied, show);
    }, delay);
    // How can I clear my timer on componentWillUnmount
  };

  const copyToClipboard = (copy, index) => {
    copyTextToClipboard(copy);
    setClipboardData(index, true, true);
    setClipboardTimer(index, true, false, 2500);
    setClipboardTimer(index, false, true, 3000);
  };
};

1 个答案:

答案 0 :(得分:0)

由于我不知道其他函数在状态方面的作用(如copyTextToClipboard,setClipboardData ...等),因此使用和测试计时器的更简单方法是使用组件类。

例如,这是一个简单的组件类,可将渲染时间延迟5秒:

class Timer extends Component {
    state = { requestTimeout: false };

    // **optional** only rerenders the component if the requestTimeout state has been changed
    // this ensures that other state/props changes and/or a parent component 
    // that has its own updating state, won't update this component
    shouldComponentUpdate = (nextProps, nextState) =>
        nextState.requestTimeout !== this.state.requestTimeout);

    // if the component unloads before the 5000ms timeout, clear it
    componentWillUnmount = () => this.clearTimer();

    // a class field to clear the timer that was set in this.requestTimeout
    clearTimer = () => clearTimeout(this.requestTimeout);

    // a class field to update state and clear the timeout
    requestTimedout = () =>
        this.setState({ requestTimeout: true }, () => this.clearTimer());

    // a class field to set this.requestTimeout to a timer that will trigger 
    // this.requestTimedout after a 5000ms delay
    setRequestTimer = () => 
        this.requestTimeout = setTimeout(this.requestTimedOut, 5000);

    // if requestTimeout state is true (?) show hello (:) else show loading
    render = () => this.state.requestTimeout ? <p>Hello</p> : <p>Loading...</p>
}

当您开始处理钩子时,当/如果在计时器仍在运行时更新了已安装的功能组件时,您将需要一种方法来保留相同的计时器(否则,每次都会继续创建新的计时器)功能组件会退回)。

例如,我有一个演示here,其中涉及使用setIterval。如您所见(单击源< >按钮),它涉及到在功能组件的状态已更新时利用useRef对象来保留相同的setInterval计时器。然后,我利用几个回调函数来设置/暂停/清除间隔。此外,它利用useEffect钩子检查它是否仍在运行,如果是,它将在return语句中清除。

简而言之,尽管您可以使用setTimeout从我的setIterval钩子演示中实现相同的目的,但我发现类更易于使用和理解(尤其是当状态正在更新并且需要更新状态时)同步处理)。