运行 设置从另一个 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]);
请注意,这有两个问题:
- Linters 会抱怨没有
state.Trade.length
作为 dep,但你只是用它来控制值
setInterval
只是使用时间作为提示。如果你想要一个适当的倒计时。您应该测量两次调用之间的时间并调整 1000 毫秒间隔。
我可以根据您提出的问题和您提供的参考代码给您一些尝试。
- 不要在 useEffect 中传递任何依赖项,因为它只会在依赖项更改时执行。将依赖项数组保持空白,然后它将像 componentDidMount() 一样工作。
- 您可以简单地使用 setTimeOut() 函数在挂载组件时等待 60 秒,然后在其中执行您的逻辑。
- 我不建议在 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]);
我想在用户点击另一个组件时触发 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]);
请注意,这有两个问题:
- Linters 会抱怨没有
state.Trade.length
作为 dep,但你只是用它来控制值 setInterval
只是使用时间作为提示。如果你想要一个适当的倒计时。您应该测量两次调用之间的时间并调整 1000 毫秒间隔。
我可以根据您提出的问题和您提供的参考代码给您一些尝试。
- 不要在 useEffect 中传递任何依赖项,因为它只会在依赖项更改时执行。将依赖项数组保持空白,然后它将像 componentDidMount() 一样工作。
- 您可以简单地使用 setTimeOut() 函数在挂载组件时等待 60 秒,然后在其中执行您的逻辑。
- 我不建议在 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]);