【发布时间】:2019-07-16 07:48:35
【问题描述】:
我在一个循环中运行一个计数器,该计数器在每个循环单击一个按钮时启动。但我无法使用索引停止特定循环的计数器。停止一个索引的计数器会停止所有其他计数器,因为我使用了 SetInetrval 和 ClearInterval。 请建议我实现这一目标的最佳方法。
提前谢谢你。
我尝试通过调用 setInterval 的 clearInterval 停止计数器 但由于索引访问行为,我无法附加它。
我是 js 中复杂循环的新手。您的帮助将不胜感激。谢谢
class RecordDuration extends Component {
constructor(props) {
super(props);
this.state = {
patientId: props.patientId ? props.patientId : null,
FromDate: new Date(),
time: null,
isStart: [],
isSave: [],
secondsElapsed: [] // this tha array for the value of the counter
}
}
renderLoading() {
if (this.state.isLoading) {
return (
<div className="full_loader">
<div className="circle_loader page_loader">
<img src={Loader} alt="" />
</div>
</div>
);
}
}
componentWillMount = () => {
this.props.PatientRecordDurationDataList(this.state.patientId)
}
componentWillReceiveProps = (nextProps) => {
if( nextProps.recordDurationDataList.data !== undefined) {
let clikcedData = this.state.isStart
let saveData = this.state.isSave
let counterData = this.state.secondsElapsed
let patientBehaviorsReductionData = nextProps.recordDurationDataList.data.PatientBehaviorsReductionData;
patientBehaviorsReductionData.map((obj, index) => {
return saveData[index] = false;
})
patientBehaviorsReductionData.map((obj, index) => {
return clikcedData[index] = false;
})
patientBehaviorsReductionData.map((obj, index) => {
return counterData[index] = 0;
})
this.setState({
isStart: clikcedData,
isSave: saveData,
secondsElapsed: counterData
})
}
}
componentWillUnmount = () => {
clearInterval(this.incrementer)
}
// This method is for start counter
handleStart = (index) => {
var _this = this;
const isStart = this.state.isStart
isStart[index] = true
_this.setState({
isStart: isStart
});
//this particular incrementer is the issue
this.incrementer = setInterval(() => {
let secondsElapsed = _this.state.secondsElapsed
secondsElapsed[index] = secondsElapsed[index] + 1
_this.setState({
secondsElapsed : secondsElapsed
})
}, 1000)
}
// This method is for Stop Counter
handleStop = (index) => {
let isStart = this.state.isStart
let isSave = this.state.isSave
isStart[index] = false
isSave[index] = true
this.setState({
isStart: isStart,
isSave: isSave
});
clearInterval(this.incrementer)
}
// This method is for Cancel the counter.
handleCancel = (index) => {
if(this.props.recordDurationDataList.data !== undefined) {
let counterData = this.state.secondsElapsed
let patientBehaviorsReductionData = this.props.recordDurationDataList.data.PatientBehaviorsReductionData;
patientBehaviorsReductionData.map((obj, index) => {
return counterData[index] = 0;
})
this.setState({
secondsElapsed: counterData
})
clearInterval(this.incrementer)
}
let clikcedData = this.state.isStart
let isSave = this.state.isSave
clikcedData[index] = false
isSave[index] = false
this.setState({
isStart: clikcedData,
isSave: isSave,
});
}
handleSave = (index) => {
}
getSeconds = (index) => {
return ('0' + this.state.secondsElapsed[index] % 60).slice(-2)
}
getMinutes = (index) => {
return Math.floor(this.state.secondsElapsed[index] / 60)
}
// this functiomn will be called by the parent render function
renderData = (dataList) => {
let PatientRecordFrequencyData = dataList || [];
if (!PatientRecordFrequencyData.length) {
return (
<tr>
<td>
<div className="text-center no-record">{this.props.loading ? 'Loading please wait...' : 'No record found.'}</div>
</td>
</tr>
);
}
return PatientRecordFrequencyData.map((Obj, index) => {
return (
<tr key={index}>
<td>
{Obj.behaviorName}
<div className="row">
<div className="col-sm-12 btn_lt reset-btn mt-10">
{(this.state.isStart[index] === false && this.state.isSave[index] === false) &&
<RaisedButton
label="START"
primary={true}
onTouchTap={() => this.handleStart(index)} />
}
{(this.state.isStart[index] === true && this.state.isSave[index] === false) &&
<div>
<span>
<RaisedButton
label="STOP"
primary={true}
onTouchTap={() => this.handleStop(index)} />
</span>
<span style={{ marginLeft: '20px' }}>
<RaisedButton
label="CANCEL"
primary={true}
onTouchTap={() => this.handleCancel(index)} />
</span>
</div>
}
{this.state.isSave[index] === true &&
<div>
<span>
<RaisedButton
label="SAVE"
primary={true}
onTouchTap={() => this.handleSave(index)} />
</span>
<span style={{ marginLeft: '20px' }}>
<RaisedButton
label="CANCEL"
primary={true}
onTouchTap={() => this.handleCancel(index)} />
</span>
</div>
}
</div>
</div>
</td>
<td>
{Obj.description}
</td>
<td>
{this.getMinutes(index)}:{this.getSeconds(index)}
</td>
</tr>
)
})
}
}
【问题讨论】:
-
据我所知,您只有一个增量器,而您说要为每个计数器分别增加值。我猜
this.incrementer应该是一个间隔数组,您可以在需要时单独清除。this.incrementers[index] = setInterval(() => /* do stuff*/, time)开始和clearInterval(this.incrementers[index])。您还应该将secondsElapsed保存在一个数组中。 -
我将 secondElapsed 保存为一个数组,我也尝试了您的解决方案,但不幸的是现在没有运气。任何其他想法@GaëlS
-
你能设置一个codesandbox吗?根据正在运行的项目帮助您会更容易。
-
@GaëlS 感谢您的时间和反馈。我解决了所有问题。干杯!!!
标签: javascript arrays reactjs counter