Reactjs 如何使用`onClick`事件停止调用useEffect钩子调用的函数?

Reactjs 如何使用`onClick`事件停止调用useEffect钩子调用的函数?,reactjs,react-hooks,setinterval,clearinterval,use-effect,Reactjs,React Hooks,Setinterval,Clearinterval,Use Effect,如何使用onClick事件停止循环函数调用?由于使用useEffect、setInterval和clearInterval,函数调用重复出现 如中所示,下面的代码将永远运行。如何在单击后停止调用函数 import React, { useState, useEffect } from 'react'; const IntervalExample = () => { const [seconds, setSeconds] = useState(0); useEffect(() =

如何使用onClick事件停止循环函数调用?由于使用useEffect、setInterval和clearInterval,函数调用重复出现

如中所示,下面的代码将永远运行。如何在单击后停止调用函数

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

const IntervalExample = () => {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        {seconds} seconds have elapsed since mounting.
      </header>
    </div>
  );
};

export default IntervalExample;

我会像这样从useffect函数中取出interval const

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

const IntervalExample = () => {
  const [seconds, setSeconds] = useState(0);
  let interval;

  useEffect(() => {
    interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);


  const handleClick = () => {
    if (interval) {
      clearInterval(interval);
    }
  }

  return (
    <div className="App">
      <header className="App-header" onClick={() => handleClick()}>
        {seconds} seconds have elapsed since mounting.
      </header>
    </div>
  );
};

export default IntervalExample;

我会像这样从useffect函数中取出interval const

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

const IntervalExample = () => {
  const [seconds, setSeconds] = useState(0);
  let interval;

  useEffect(() => {
    interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);


  const handleClick = () => {
    if (interval) {
      clearInterval(interval);
    }
  }

  return (
    <div className="App">
      <header className="App-header" onClick={() => handleClick()}>
        {seconds} seconds have elapsed since mounting.
      </header>
    </div>
  );
};

export default IntervalExample;
添加另一个名为running的状态,并使useEffect依赖于它。每当running被切换为false时,useffect的cleanup函数就会清除间隔。由于running为false,我们跳过设置新的间隔。无论何时将其切换为true,它都将重新启动

const{useState,useffect,useCallback}=React; 常量IntervalExample==>{ const[seconds,setSeconds]=useState0; const[running,setRunning]=useStatetrue; const toggleRunning=useCallback =>setRunningrun=>!运行 , []; useEffect=>{ 如果!跑{ //setSeconds0;//如果还想重置它 回来 } const interval=setInterval=>{ setSecondSeconds=>seconds+1; }, 1000; return=>clearIntervalinterval; },[跑步]; 回来 {seconds}装载后已过秒。 {正在运行?'running':'stopped'} ; }; ReactDOM.render , 根 ; 添加另一个名为running的状态,并使useEffect依赖于它。每当running被切换为false时,useffect的cleanup函数就会清除间隔。由于running为false,我们跳过设置新的间隔。无论何时将其切换为true,它都将重新启动

const{useState,useffect,useCallback}=React; 常量IntervalExample==>{ const[seconds,setSeconds]=useState0; const[running,setRunning]=useStatetrue; const toggleRunning=useCallback =>setRunningrun=>!运行 , []; useEffect=>{ 如果!跑{ //setSeconds0;//如果还想重置它 回来 } const interval=setInterval=>{ setSecondSeconds=>seconds+1; }, 1000; return=>clearIntervalinterval; },[跑步]; 回来 {seconds}装载后已过秒。 {正在运行?'running':'stopped'} ; }; ReactDOM.render , 根 ;
我认为停止是指点击事件的clearInterval。因此,在新的状态变量中保存区间id的最佳方法


const IntervalExample = () => {
  const [seconds, setSeconds] = useState(0);
  const [currentIntervalId, setIntervalId] = useState(null);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
    setIntervalId(interval);
    return () => clearInterval(interval);
  }, []);

  const stopInterval = () => {
    clearInterval(currentIntervalId);
  };

  return (
    <div className="App">
      <header className="App-header" onClick={stopInterval}>
        {seconds} seconds have elapsed since mounting.
      </header>
    </div>
  );
};
为什么在美国? 因为这将使您能够更灵活地重新启动间隔或根据事件随时停止。
注意:您也可以将其放在useEffect范围之外定义的变量中。

我认为停止意味着在单击事件上说clearInterval。因此,在新的状态变量中保存区间id的最佳方法


const IntervalExample = () => {
  const [seconds, setSeconds] = useState(0);
  const [currentIntervalId, setIntervalId] = useState(null);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
    setIntervalId(interval);
    return () => clearInterval(interval);
  }, []);

  const stopInterval = () => {
    clearInterval(currentIntervalId);
  };

  return (
    <div className="App">
      <header className="App-header" onClick={stopInterval}>
        {seconds} seconds have elapsed since mounting.
      </header>
    </div>
  );
};
为什么在美国? 因为这将使您能够更灵活地重新启动间隔或根据事件随时停止。
注意:您也可以将其放在useEffect范围之外定义的变量中。

您基本上不能这样做,因为您声明它是一个常量,在useEffect中没有任何东西可以更改它的值,因此任何东西都无法达到它。但是你可以在use effect之外声明它,并在秒或类似的时间内使用useEffect更改interval的值。你基本上不能这样做,因为你声明它是一个常量,在useEffect内没有任何东西可以更改它的值,所以任何东西都无法达到它。但是你可以在use effect之外声明它,并在秒或类似的时间内使用useEffect更改interval的值。对这种方法有疑问,当我们更新running hook时,它不会卸载组件,因此清理不会工作。此时您将生成一个新的间隔id,而旧的间隔不会被清除。我说的对吗?无论何时,都会调用清理:此外,如果组件像通常那样多次渲染,则在执行下一个效果之前会清理上一个效果。。如果没有,setInterval将继续调用setSeconds。对此方法有疑问,当我们更新running hook时,它不会卸载组件,因此清理将无法工作。此时您将生成一个新的间隔id,而旧的间隔不会被清除。我说的对吗?无论何时,都会调用清理:此外,如果组件像通常那样多次渲染,则在执行下一个效果之前会清理上一个效果。。如果没有,则setInterval将继续调用setSeconds.interval在handleClick函数中似乎未定义,且上述代码似乎不起作用。interval在handleClick函数中似乎未定义,且上述代码似乎不起作用