如何使用onClick
事件来停止重复发生的函数调用?由于使用了useEffect
,setInterval
和clearInterval
,因此函数调用重复进行。
this article中所示的示例,以下代码将永远运行。一旦单击<header></header>
,如何停止调用该函数?
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;
答案 0 :(得分:1)
我会像这样从useEffect函数中拉出间隔const。
<div class="input-field col s12">
<select id="country-list" onchange="changeCountry(this)">
<option value="none" disabled selected>Choose your option</option>
<option value="Ukraine">Ukraine </option>
<option value="Poland">Poland</option>
</select>
</div>
<div class="input-field col s12">
<select id="city-list">
<option value="none" disabled selected>Choose your option</option>
</select>
</div>
答案 1 :(得分:1)
添加另一个名为running
的状态,并使useEffect
依赖于该状态。每当将running
切换到false
时,间隔就会由useEffect
的清除功能清除。由于running
是false
,因此我们跳过设置新间隔的过程。每当将其切换为true
时,它将重新启动。
const { useState, useEffect, useCallback } = React;
const IntervalExample = () => {
const [seconds, setSeconds] = useState(0);
const [running, setRunning] = useState(true);
const toggleRunning = useCallback(
() => setRunning(run => !run)
, []);
useEffect(() => {
if(!running) {
// setSeconds(0); // if you want to reset it as well
return;
}
const interval = setInterval(() => {
setSeconds(seconds => seconds + 1);
}, 1000);
return () => clearInterval(interval);
}, [running]);
return (
<div className="App">
<header className="App-header">
{seconds} seconds have elapsed since mounting.
</header>
<button
onClick={toggleRunning}
>
{running ? 'running' : 'stopped'}
</button>
</div>
);
};
ReactDOM.render(
<IntervalExample />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
答案 2 :(得分:1)
我认为阻止您的意思是在点击事件中说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
范围之外定义的变量中。