1 回答
TA贡献1856条经验 获得超17个赞
这些测试失败的原因是因为timeLeftSeconds
一旦时钟进入“中断”周期,状态就没有正确设置,反之亦然。我在下面做了必要的调整。decreaseCurrentSecond
注意和方法的变化down
。
此外,永远不要像您在此处所做的那样尝试直接更新状态中的值 - decreaseCurrentSecond = () => this.state.timeLeftSeconds--;
。这不是好的做法——为什么我不能直接修改组件的状态,真的吗?
import React from "react";
import ReactDOM from "react-dom";
import "./style.css";
/*
* A simple React component
*/
const initState = {
breakLength: 0.5,
sessionLength: 0.5,
init: "session",
// stateIndex: 0,
timeLeft: undefined,
timeLeftSeconds: undefined,
started: false,
intervalFunc: undefined
};
const secondsToMins = (time) => {
let converted =
("0" + Math.floor(time / 60)).slice(-2) +
":" +
("0" + Math.floor(time % 60)).slice(-2);
return converted;
};
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = initState;
this.breakDecrement = this.breakDecrement.bind(this);
this.breakIncrement = this.breakIncrement.bind(this);
this.sessionDecrement = this.sessionDecrement.bind(this);
this.sessionIncrement = this.sessionIncrement.bind(this);
this.startStop = this.startStop.bind(this);
this.reset = this.reset.bind(this);
}
componentDidMount() {
let sessionSeconds = this.state.sessionLength * 60;
this.setState({ timeLeftSeconds: sessionSeconds });
this.setState({ timeLeft: secondsToMins(sessionSeconds) });
}
breakDecrement() {
console.log("break decrement");
// decrements the breakLength and the breakSeconds
// breakLength is only a number ie. 5 (does not show seconds)
// breakSeconds is that nunber converted into seconds
let breakLength = this.state.breakLength - 1;
if (breakLength > 0 && breakLength < 61) {
this.setState({ breakLength: breakLength });
// let breakSeconds = breakLength * 60;
// states[1]["duration"] = breakSeconds;
}
}
breakIncrement() {
// same as decrement except does increment
let breakLength = this.state.breakLength + 1;
if (breakLength > 0 && breakLength < 61) {
this.setState({ breakLength: breakLength });
// let breakSeconds = breakLength * 60;
// states[1]["duration"] = breakSeconds;
}
}
sessionDecrement() {
// decrements the sessionLength and the sessionSeconds
// sessionLength is only a number ie. 25 (does not show seconds)
// sessionSeconds is that nunber converted into seconds
let sessionLength = this.state.sessionLength - 1;
if (sessionLength > 0 && sessionLength < 61) {
// states[0]["duration"] = sessionLength * 60;
this.setState((prevState) => ({
sessionLength: prevState.sessionLength - 1,
timeLeftSeconds: (prevState.sessionLength - 1) * 60,
timeLeft: secondsToMins((prevState.sessionLength - 1) * 60)
}));
}
}
sessionIncrement() {
// same as decrement except does increment
let sessionLength = this.state.sessionLength + 1;
if (sessionLength > 0 && sessionLength < 61) {
// states[0]["duration"] = sessionLength * 60;
this.setState((prevState) => ({
sessionLength: prevState.sessionLength + 1,
timeLeftSeconds: (prevState.sessionLength + 1) * 60,
timeLeft: secondsToMins((prevState.sessionLength + 1) * 60)
}));
}
}
startStop(id) {
// starts the countDown, which runs continuously until the start/stop button
// is pressed again, which pauses the countdown.
// the id parameter is used by countDown to play the audio beep
if (!this.state.started) {
this.setState({ started: true });
this.countDown(id);
}
// pauses the countDown
if (this.state.started) {
this.setState({ started: false });
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
}
}
reset() {
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
// reset state to default values
this.setState({ breakLength: 5 });
this.setState({ sessionLength: 25 });
this.setState({ init: "session" });
this.setState({ timeLeftSeconds: 1500 });
this.setState({ timeLeft: "25:00" });
// this.setState({ stateIndex: 0 });
this.setState({ started: false });
this.setState({ intervalFunc: undefined });
}
decreaseCurrentSecond = () =>
//this.state.timeLeftSeconds--;
{
this.setState({
timeLeftSeconds: this.state.timeLeftSeconds - 1
});
return this.state.timeLeftSeconds;
};
countDown(id) {
// set the function to a variable and set state to it, so the function
// can be paused with clearInterval()
var intervalFunc = setInterval(
() => down(this.decreaseCurrentSecond()),
1000
);
this.setState({ intervalFunc: intervalFunc });
const down = (time) => {
if (time > 0) {
// converts seconds to MM:SS at every t-minus
this.setState({ timeLeft: secondsToMins(time) });
/*
console.log(time);
console.log(this.state.timeLeft);*/
}
let sound = document.getElementById(id).childNodes[0];
if (time <= 0) {
sound.play();
this.setState({ timeLeft: secondsToMins(time) });
console.log(`##########`);
console.log(time);
// console.log(this.stateIndex);
console.log(this.state.init);
console.log(this.state.timeLeftSeconds);
console.log(`##########`);
// let stateIndex = (this.state.stateIndex + 1) % states.length;
// this.setState({ stateIndex: stateIndex });
this.setState({
init: this.state.init === "session" ? "break" : "session"
});
this.setState({
timeLeftSeconds:
this.state.init === "session"
? this.state.sessionLength * 60 + 1
: this.state.breakLength * 60 + 1
});
console.log(`##########`);
console.log(time);
// console.log(this.stateIndex);
console.log(this.state.init);
console.log(this.state.timeLeftSeconds);
console.log(`##########`);
}
};
// down(this.decreaseCurrentSecond());
}
render() {
return (
<div id="clock">
<h1 id="title">25-5 Clock</h1>
<div>
<p id="break-label">Break Length</p>
<p id="break-length">{this.state.breakLength}</p>
<button id="break-decrement" onClick={(e) => this.breakDecrement()}>
{" "}
Decrease{" "}
</button>
<button id="break-increment" onClick={(e) => this.breakIncrement()}>
{" "}
Increase{" "}
</button>
</div>
<div>
<p id="session-label">Session Length</p>
<p id="session-length">{this.state.sessionLength}</p>
<button
id="session-decrement"
onClick={(e) => this.sessionDecrement()}
>
{" "}
Decrease{" "}
</button>
<button
id="session-increment"
onClick={(e) => this.sessionIncrement()}
>
{" "}
Increase{" "}
</button>
</div>
<hr />
<div>
<p id="timer-label">{this.state.init}</p>
<p id="time-left">{this.state.timeLeft}</p>
<button id="start_stop" onClick={(e) => this.startStop(e.target.id)}>
<audio id="beep" src="./beep.mp3"></audio> start/stop{" "}
</button>
<button id="reset" onClick={(e) => this.reset()}>
{" "}
reset{" "}
</button>
</div>
</div>
);
}
}
/*
* Render the above component into the div#app
*/
ReactDOM.render(<Clock />, document.getElementById("app"));
https://codesandbox.io/s/heuristic-star-i3t8m?file=/src/index.js
添加回答
举报