我正在设置一个计时器,我试图使子组件“ Timer”与父组件“ App”进行通信,以便父组件可以更改计时器(一个用于锻炼时间,另一个用于休息时间。时间);但无法正常运行,则该应用会启动,但不会更改计时器。 我是编码和StackOverflow的新手,所以我希望任何人在此问题上有任何指导和建议。
我正在尝试使用useEffect
钩子将计时器达到“ 0”值时将状态“更改”设置为“真”。然后我想在“ change”为“ true”时调用一个函数,该函数从需要将状态从“ ExerciseTime”更改为“!ExerciseTime”的父“ App”调用上述函数。显然到目前为止还没有工作...
这是父组件(我将其简化为仅存在实际问题的部分):
function App() {
const [exerciseTime, setExerciseTime] = useState(true);
const handleTimer = () => {
setExerciseTime(!exerciseTime);
};
return (
</div>
{exerciseTime ? <Timer time={5} change ={handleTimer()} /> : <Timer
time={3} change ={handleTimer} />}
<div>
);
}
这是子组件:
const Timer = props => {
const [seconds, setSeconds] = useState(props.time);
const [isActive, setIsActive] = useState(false);
const [change, setChange] = useState(false);
const toggle = () => {
setIsActive(!isActive);
};
if (change) {
props.change();
}
useEffect(() => {
let interval = null;
function changing() {
setChange(!change);
}
if (isActive && seconds !== 0) {
interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
}, 1000);
} else if (!isActive && seconds !== 0) {
clearInterval(interval);
} else if (seconds === 0) {
changing();
clearInterval(interval)
}
return () => clearInterval(interval);
}, [isActive, seconds, change]);
return (
<div className="timer">
<div className="timer-seconds">{seconds}</div>
<div className="config-button">
<button
className={`button button-${isActive ? "active" : "inactive"}`}
onClick={toggle}
>
{isActive ? "Pause" : "Start"}
</button>
</div>
</div>
);
};
我希望计时器在到达“ 0”值时更改为新的计时器,依此类推...
答案 0 :(得分:1)
首先:您需要使用引用-handleTimer
而不是调用函数handleTimer()
。
第二:您做的方式是开始太多的时间间隔。这会破坏您的应用程序。
第三:即使时间道具发生变化,计时器组件也不会卸载,因此一旦计时器结束,该值将为0而不是3或5。
有更好的方法可以执行此操作,但是我不想离开您正在做的事情,因此请对其进行修改以使其起作用。
const Timer = props => {
const [seconds, setSeconds] = React.useState(props.time);
const [isActive, setIsActive] = React.useState(false);
const toggle = () => {
setIsActive(!isActive);
};
React.useEffect(
() => {
let interval;
if (isActive && seconds !== 0) {
interval = setInterval(
() => setSeconds(seconds => seconds - 1), 1000
);
}
if (isActive && seconds === 0) {
setIsActive(false)
props.change()
}
return () => {
clearInterval(interval)
}
}, [isActive, seconds]);
return (
<div className="timer">
<div className="timer-seconds">{seconds}</div>
<div className="config-button">
<button
className={`button button-${isActive ? "active" : "inactive"}`}
onClick={toggle}
>
{isActive ? "Pause" : "Start"}
</button>
</div>
</div>
);
};
function App() {
const [exerciseTime, setExerciseTime] = React.useState(true);
const handleTimer = () => {
setExerciseTime((exTime) => !exTime);
};
return (
<div key={exerciseTime}>
{exerciseTime ? <Timer time={5} change={handleTimer} /> : <Timer
time={3} change={handleTimer} />
}
</div>
);
}
export default App
编辑:
答案 1 :(得分:0)
您想将函数而不是函数的返回值传递给变更处理程序:
{exerciseTime ? <Timer time={5} change ={handleTimer} /> : <Timer time={3} change ={handleTimer} />}
基本上handleTimer()
应该变成handleTimer
。