2017-02-23 25 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

Есть много способов сделать это. Вы можете сохранить идентификатор текущего таймера в состоянии MainSection и изменить его с TodoItem с функцией обратного вызова, например completeTodo. Затем, вы можете отправить этот атрибут MainSection состояния для каждого TodoItem в качестве опоры и проверьте в ней, если это тот, который работает:

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

Все дело в том, что вам нужно общаться с MainSection который TodoItem является или, по крайней мере, если работает TodoItem. Насколько я могу видеть все, что вы сохраняете о состоянии таймера, является локальным для состояния TodoItem, поэтому другие TodoItems не могут знать, должны ли они запускаться или нет.

A TODO список almost a classic example of the Redux usage. Я не знаю, можете ли вы представить Redux в своем приложении, но это определенно отличный инструмент, когда дело доходит до хранения глобального состояния.

+0

Да, я использую Redux в своем приложении, и я просто переписываю «классический пример» с моими функциями. Так или иначе мне нужно общаться с MainSection, я прав? –

+0

Либо вы познакомились с MainSection, либо используете магазин Redux. Например, если вы сохраняете идентификатор текущего элемента с Redux, вам не нужно будет хранить его в MainSection. –

Смежные вопросы