运行 设置从另一个 React 组件点击时的间隔

Run set interval when click from another component React

我想在用户点击另一个组件时触发 60 秒的倒计时。到目前为止我没有找到任何解决方案

 const [seconds, setSeconds] = useState(60)
 useEffect(() => {
    console.log(state.Trade.length ,"woking in useeffect ");
    setInterval(() => {
      setSeconds(prevState => prevState - 1)
    }, 1000);
 }, [state.Trade.length]);


 // also use without use effect 


    const startCounter = () => { 
  setInterval(() => {
    setSeconds(prevState => prevState - 1)
  }, 1000);
 }
if (state.Trade.length!=0) {
  if (seconds==0) return null
  startCounter()
 
}else{
  return null
}

它不起作用我搜索了很多但没有find.Thanks

useEffect会在state.Trade.length变化时触发。

您可能需要依赖于 seconds

像这样:

const [seconds, setSeconds] = useState(60)
 useEffect(() => {
    console.log(state.Trade.length ,"woking in useeffect ");
    setInterval(() => {
      setSeconds(prevState => prevState - 1)
    }, 1000);
 }, [seconds]);

请注意,这有两个问题:

  1. Linters 会抱怨没有 state.Trade.length 作为 dep,但你只是用它来控制值
  2. setInterval 只是使用时间作为提示。如果你想要一个适当的倒计时。您应该测量两次调用之间的时间并调整 1000 毫秒间隔。

我可以根据您提出的问题和您提供的参考代码给您一些尝试。

  1. 不要在 useEffect 中传递任何依赖项,因为它只会在依赖项更改时执行。将依赖项数组保持空白,然后它将像 componentDidMount() 一样工作。
  2. 您可以简单地使用 setTimeOut() 函数在挂载组件时等待 60 秒,然后在其中执行您的逻辑。
  3. 我不建议在 useEffect 中使用 setSeconds,因为它的依赖项是秒变量本身。这可能会导致无限渲染(如此处的答案之一所示)。

编辑 1:所以我在下面所做的是在单击按钮时将状态变量更改为 1 以模拟您的场景。然后在一个 useEffect 中,我为 seconds 变量设置一个间隔 -1,这里是 5,但你可以将它设置为 60。在 ummount 上,间隔将被清除。第二个 useEffect 只是在 seconds 每秒变化时进行记录。

const[state,setState]=useState(0)
const[seconds, setSeconds]=useState(5)
useEffect(()=>{
    let secondsInterval;
    if(state===1){
        secondsInterval=setInterval(()=>{
            setSeconds(prev=>prev-1)
        },1000)
    }
    return()=>clearInterval(secondsInterval)
},[state])

useEffect(()=>{
    console.log("Time remaining: "+seconds);
},[seconds])

记得清除你的间隔

const [seconds, setSeconds] = useState(60);
useEffect(() => {
    const intervalId = setInterval(() => {
      setSeconds((prevState) => {
        if(prevState === 1) clearInterval(intervalId)
        return prevState - 1;
      });
    }, 1000);
}, [state.Trade.length]);