如何基于React中的索引停止在循环中运行的计数器

时间:2019-07-16 07:48:35

标签: javascript arrays reactjs counter

我在循环中运行一个计数器,该计数器在每次循环中都单击一个按钮就开始了。但是我无法停止使用索引的特定循环计数器。由于使用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>
                    )
                })
            }
        }

1 个答案:

答案 0 :(得分:0)

我通过管理索引的状态解决了这个问题,请立即查看代码

class RecordDuration extends Component {

    constructor(props) {
        super(props);
        this.state = {
            patientId: props.patientId ? props.patientId : null,
            FromDate: new Date(),
            time: null,
            isStart: [],
            isSave: [],
            secondsElapsed: [],
            incrementer: [],
        }
    }

    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 = () => {         
        this.state.incrementer.map((obj, index) => {
            return clearInterval(this.state.incrementer[index]);
        })      
    }

    handleStart = (index) => {
        var _this = this;
        const isStart = this.state.isStart
        isStart[index] = true
        _this.setState({
            isStart: isStart
        });

        let incrementer = this.state.incrementer

        incrementer[index] = setInterval(() => {
            let secondsElapsed = _this.state.secondsElapsed
            secondsElapsed[index] = secondsElapsed[index] + 1
            _this.setState({
                secondsElapsed : secondsElapsed
            })
        }, 1000)

        _this.setState({
            incrementer: incrementer
        });

    }

    handleStop = (index) => {
        let isStart = this.state.isStart
        let isSave = this.state.isSave
        let counterData = this.state.secondsElapsed
        isStart[index] = false
        isSave[index] = true
        counterData[index];
        this.setState({
            isStart: isStart,
            isSave: isSave,
            secondsElapsed: counterData
        },clearInterval(this.state.incrementer[index]));
    }

    handleCancel = (index) => {
        let clikcedData = this.state.isStart
        let isSave = this.state.isSave
        let counterData = this.state.secondsElapsed
        clikcedData[index] = false
        isSave[index] = false
        counterData[index] = 0;
        this.setState({
            isStart: clikcedData,
            isSave: isSave,
            secondsElapsed: counterData
        }, clearInterval(this.state.incrementer[index]));

    }


    handleSave = (index) => {

    }

    getSeconds = (index) => {
        return ('0' + this.state.secondsElapsed[index] % 60).slice(-2)
    }

    getMinutes = (index) => {
        return Math.floor(this.state.secondsElapsed[index] / 60)
    }


    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>
            )
        })
    }

    renderRecordDuration = () => {
        const tableClass = classNames({
            'table': true,
            'table-striped': this.props.condensed,
            'table-bordered': this.props.bordered,
            'table-hover': true,
            'table-condensed': this.props.condensed,
            'customtable': true,
        });
        const { recordDurationDataList } = this.props;
        let PatientRecordDurationList = (recordDurationDataList && recordDurationDataList.data) || [];
        return (
            <div className="table-responsive mt-15">
                <table className={tableClass}>
                    <thead>
                        <tr>
                            <th width="40%">Duration</th>
                            <th width="40%"></th>
                            <th width="20%"></th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.renderData(PatientRecordDurationList.PatientBehaviorsReductionData)}
                    </tbody>
                </table>
            </div>
        )
    }


    render() {

        return (
            <div>
                {this.renderLoading()}

                <div className="clearfix"></div>
                <div className="readmin-panel">
                    <div className="panel-body">
                        <div className="row">
                            {this.renderRecordDuration()}
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}