[英]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.