2017-02-23 38 views
0

我感覺自己完全困惑,因爲我仍然從昨天開始在這個問題上工作,沒有任何幫助。 所以,問題:我有待辦事項列表。每個任務都有計時器。只有一個定時器可以同時工作,因此用戶只能同時完成一項任務。 我以爲我可以做'開始'按鈕在另一個任務被禁用,當一個計時器運行,但我認爲我在我的setState錯誤,因爲所有的計時器仍然在一起運行=( 我閱讀文檔,但它不是對我來說很有幫助。 另外,我有文件TodoTextInput,這是產生這些任務,我想,也許我應該在這裏貼上我的計時器,但很奇怪。一次性工作計時器

對於完整的信息,我離開這裏的兩個文件。 謝謝你任何幫助!

的TodoItem(這裏的問題)

import React, { Component, PropTypes } from 'react' 
import classnames from 'classnames' 
import TodoTextInput from './TodoTextInput' 

export default class TodoItem extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { secondsStart: this.props.minSeconds, timerRunning: false } 
    } 

    static propTypes = { 
    todo: PropTypes.object.isRequired, 
    deleteTodo: PropTypes.func.isRequired, 
    completeTodo: PropTypes.func.isRequired, 
    } 

    static defaultProps = { 
     minSeconds: 0 
    } 
    handleSave = (id, text) => { 
    if (text.length === 0) { 
     this.props.deleteTodo(id) 
    } 
    } 

handleStartClick =() => { 
    if (!this.state.timerRunning) { 
     this.incrementer = setInterval(() => { 
     this.setState({ 
      secondsStart: (this.state.secondsStart + 1) 
     }); 
     }, 1000) 
     this.setState({ 
     timerRunning: true, 
     currentTodoId: this.props.todo.id, 
     runningTodoId: this.props.todo.id 
     }); 
    } 
    } 


    getSeconds =() => { 
    return ('0' + this.state.secondsStart % 60).slice(-2) 
    } 

    getMinutes =() => { 
    return Math.floor((this.state.secondsStart/60)%60) 
    } 
    getHoures =() => { 
    return Math.floor((this.state.secondsStart/3600)%24) 
    } 


    handleStopClick =() => { 
    clearInterval(this.incrementer) 
    this.setState({ timerRunning: false, currentTodoId: null, runningTodoId: null }); 
    } 

    render() { 
    const { todo, completeTodo, deleteTodo} = this.props 

    const element = this.state.todo ? (
     <TodoTextInput text={todo.text} 
     onSave={(text) => this.handleSave(todo.id, text)} /> 
    ) : (
     <div className="view"> 
      <input className="toggle" 
      type="checkbox" 
      checked={todo.completed} 
      onChange={() => completeTodo(todo.isRequired)} /> 
      <label> 
      {todo.text} 
      </label> 
      <div className="buttons"> 
      <h6>{this.getHoures()}:{this.getMinutes()}:{this.getSeconds()}</h6> 
      {(this.state.secondsStart === 0) 
       ? <button className="timer-start" onClick={this.handleStartClick} disabled={this.state.timerRunning }>Start</button> 
       : <button className="timer-stop" onClick={this.handleStopClick} disabled={!this.state.timerRunning && this.state.runningTodoId !== this.state.currentTodoId}>Stop</button> 
      } 
      </div> 
      <button className="destroy" 
      onClick={() => deleteTodo(todo.id)} /> 
     </div> 
    ) 

    return (
     <li className={classnames({ 
     completed: todo.completed, 
     })}> 
     {element} 
     </li> 
    ) 
    } 
} 

TodoTextInput(以防萬一)

import React, { Component, PropTypes } from 'react' 
import classnames from 'classnames' 

export default class TodoTextInput extends Component { 
    static propTypes = { 
    onSave: PropTypes.func.isRequired, 
    text: PropTypes.string, 
    placeholder: PropTypes.string, 
    newTodo: PropTypes.bool 
    } 

    state = { 
    text: this.props.text || '' 
    } 

    handleSubmit = e => { 
    const text = e.target.value.trim() 
    if (e.which === 13) { 
     this.props.onSave(text) 
     if (this.props.newTodo) { 
     this.setState({ text: '' }) 
     } 
    } 
    } 

    handleChange = e => { 
    this.setState({ text: e.target.value }) 
    } 

    handleBlur = e => { 
    if (!this.props.newTodo) { 
     this.props.onSave(e.target.value) 
    } 
    } 

    render() { 
    return (
     <input className={ 
     classnames({ 
      'new-todo': this.props.newTodo 
     })} 
     type="text" 
     placeholder={this.props.placeholder} 
     autoFocus="true" 
     value={this.state.text} 
     onBlur={this.handleBlur} 
     onChange={this.handleChange} 
     onKeyDown={this.handleSubmit} /> 
    ) 
    } 
} 
+0

所以我明白,問題是你想在開始時禁用所有的定時器,對嗎?你在哪裏使用TodoItem組件? –

+0

是的,當我在一項任務中點擊「開始」時 - 我應該沒有機會在其他任務中點擊「開始」。只有當我點擊「停止」這個任務時,我才能運行另一個任務和計時器。 TodoItem組件我在組件MainSection中導入 - 它是應用程序的最大部分。 –

回答

0

有很多方法可以做到這一點。您可以將當前正在運行的計時器的ID保存在MainSection的狀態中,並將其從TodoItem更改爲帶有回調函數,如completeTodo。然後,你可以在MainSection狀態的此屬性發送到每個TodoItem爲道具,並在它檢查是否它是正在運行的一個:

render() { 
     const { todo, runningTodoId, startTodoTimer, completeTodo, deleteTodo} = this.props 
     let disable = runningTodoId == todo.id; 
    } 

整點是,你需要傳達給MainSectionTodoItem是運行或至少是否有TodoItem正在運行。據我可以看到所有你正在存儲的關於定時器的狀態是本地的TodoItem的狀態,所以其他TodoItems無法知道他們是否應該能夠啓動或不。

一個待辦事項列表是almost a classic example of the Redux usage。我不知道是否可以將Redux引入到您的應用中,但在存儲全局狀態時它絕對是一個很好的工具。

+0

是的,我在我的應用程序中使用Redux,我只是用我的功能重寫「經典示例」。 所以無論如何我需要與MainSection溝通,我是對的? –

+0

要麼你與MainSection交流,要麼使用Redux商店。例如,如果您使用Redux存儲當前正在運行的Item的ID,則不必將其存儲在MainSection中。 –