簡體   English   中英

反應為什么我的 clearInterval 無法停止 setInterval?

[英]React why my clearInterval cannot stop setInterval?

我對 React 完全陌生。 我嘗試實現的是一個計時器。 當點擊小時、分鍾或秒時,計時器將停止,並且當點擊輸入按鈕時,所選的計時器將變為輸入字段,它不應顯示更多輸入字段並重新開始時鍾。 它的樣子

當我單擊 flexbox 容器時,我嘗試停止將新的 props 傳遞給子組件。 我根據狀態中的更新變量編寫了一個 handleClick 函數和 setInterval() 或 clearInterval() 。

我想要的是當我單擊小時/分鍾/秒中的任何一個時,選擇字段將更改為輸入字段,並且計時器停止。 一旦我按下回車鍵,它就會回到計時器。

 class Timer extends React.Component{ constructor(props){ super (props); this.timerRef = React.createRef(); this.state = { hh: new Date().getHours().toString().padStart(2,"0"), mm: new Date().getMinutes().toString().padStart(2,"0"), ss: new Date().getSeconds().toString().padStart(2,"0"), suffix: new Date().getHours() > 12 ? "PM" : "AM", update:true, }; } tick() { this.setState({ hh: new Date().getHours().toString().padStart(2,"0"), mm: new Date().getMinutes().toString().padStart(2,"0"), ss: new Date().getSeconds().toString().padStart(2,"0"), suffix: new Date().getHours() > 12 ? "PM" : "AM", }) } componentDidMount(){ this.intervalId = setInterval( () => this.tick(), 1000 ); } componentWillUnmount(){ clearInterval(this.intervalId); } handleClick(){ this.setState(state => ({update: !state.update})); console.log("1",this.state.update); if (this.state.update){ this.intervalId = setInterval( () => this.tick(), 1000 ); console.log("2 set interval",this.intervalId); } else{ clearInterval(this.intervalId); console.log("2 clear interval"); } } render() { const { hh, mm, ss, suffix } = this.state; return ( <div className="box" > London Clock <div className="flexbox-container" onClick={() => this.handleClick()}> <Content time={hh}></Content> <div><p>:</p></div> <Content time={mm}></Content> <div><p>:</p></div> <Content time={ss}></Content> <div className="suffix"><p>{suffix}</p></div> </div> </div> ); } } class Content extends React.Component { state = { editMode: false, time: "" }; componentDidMount(){ this.setState({ time: this.props.time, }) } handleKeyDown(event){ console.log(event,event.key === 'Enter'); if (event.key === 'Enter'){ this.setState({ editMode: false, }) } } render() { const {editMode} = this.state; return ( <div> {editMode? ( <p> <input defaultValue={this.props.time} onKeyPress={e => this.handleKeyDown(e)} /> </p> ) : ( <p onClick={() => this.setState({ editMode: true })}>{this.props.time}</p> )} </div> ); } } ReactDOM.render( <Timer/>, document.body );
 .flexbox-container { display: flex; flex-direction: row; } .suffix{ padding-left: 20px; } .box{ border-style: solid; padding: 10px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

嘗試像下面這樣而不是設置狀態和綁定您的tick函數。

       componentDidMount(){
            this.intervalId = setInterval(
                () => this.tick.bind(this), 1000
            );
        }
        
        componentWillUnmount(){
            clearInterval(this.intervalId);
        }

我認為你可以使用 React 的 Ref 而不是 state。

constructor(props) {
    this.timerRef = React.createRef();
  }

  componentDidMount() {
    this.timerRef.current = setInterval(this.tick, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timerRef.current);
  }

當你的組件被掛載時,它會開始一個間隔並將它分配給intervalId

您的點擊處理程序會修改狀態,然后立即嘗試查看狀態,而無需等待更新。 此時狀態可能未更新,因此它重新分配間隔,導致僵屍更新程序。

要么將回調傳遞給setState(updater, [callback])要么將您的間隔邏輯移動到componentDidUpdate ,這將允許您刪除重復的間隔邏輯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM