2016-02-23 86 views
0

我正在使用複選框,該複選框應該通過組件的狀態更新待辦事項項目的完成狀態。當我單擊待辦事項框時,它不會更改狀態,但如果我單擊它兩次,它會更新狀態。由於我必須單擊它兩次,這意味着當該框被選中this.state.done === false並且當它取消選中this.state.done === true時。我不知道爲什麼它不會在第一次點擊時翻轉狀態。該複選框由handleDoneChange()控制。有人能告訴我爲什麼複選框不會改變第一次點擊的狀態嗎?無法正確使用複選框來更新狀態

class ShowTodo extends Component { 

    static contextTypes = { 
     router: PropTypes.object 
    }; 

    constructor(props) { 
     super(props); 

     this.state = { 
      descriptionChanged: false, 
      newDescription: '', 
      newTitle: '', 
      done: false 
     }; 


     this.handleDescriptionChange = this.handleDescriptionChange.bind(this); 
     this.handleDeleteClick = this.handleDeleteClick.bind(this); 
     this.changeButtons = this.changeButtons.bind(this); 
     this.handleSaveClick = this.handleSaveClick.bind(this); 
     this.handleUndoClick = this.handleUndoClick.bind(this); 
     this.handleTitleChange = this.handleTitleChange.bind(this); 
     this.handleDoneChange = this.handleDoneChange.bind(this); 
    } 

    componentWillMount() { 
     this.props.fetchTodo(this.props.params.id).then(() => { 
      this.setState({ 
       newDescription: this.props.todo.description, 
       newTitle: this.props.todo.title, 
       done: this.props.todo.completed 
      }); 
      console.log("This is the todo's starting completed status: ", this.state.done); 
     }); 
    } 

    render() { 

     const { todo } = this.props; 

     if (!todo) { 
      return (
       <h3>Loading...</h3> 
      ); 
     } 

     return (
      <div className="input-group"> 
       <Link to="/todos_index">Back</Link> 
       <h3>Title</h3> 
       <input 
        type="text" 
        className="form-control" 
        value={this.state.newTitle} 
        onChange={this.handleTitleChange} /> 
       <textarea 
        className="form-control" 
        value={this.state.newDescription} 
        onChange={this.handleDescriptionChange}> 
       </textarea> 
       <span className="input-group-addon"> 
        <input type="checkbox" 
         onClick={this.handleDoneChange} /> 
       </span> 
       <span className="input-group-btn"> 
        {this.changeButtons()} 
        <button onClick={this.handleDeleteClick} className="btn btn-danger pull-xs-right">Delete Post</button> 
       </span> 


      </div> 
     ); 
    } 

    changeButtons() { 
     if (!this.state.descriptionChanged) { 
      return null; 
     } else { 

      return [ 
      <button 
       className="btn btn-default" 
       onClick={this.handleSaveClick} 
       >Save</button>, 
      <button 
       className="btn btn-default" 
       onClick={this.handleUndoClick} 
       >Undo</button> 
      ]; 
     } 
    } 

    handleDescriptionChange(event) { 
     this.setState({ 
      descriptionChanged: true, 
      newDescription: event.target.value 
     }); 
     console.log('New description in state: ', this.state.newDescription); 
    } 

    handleTitleChange(event) { 
     this.setState({ 
      descriptionChanged: true, 
      newTitle: event.target.value 
     }); 
    } 

    handleDoneChange(event) { //This isn't updating the done status 

     this.setState({ 
      done: !this.state.done 
     }); 

     var id = this.props.params.id; 

     var props = { 
      completed: this.state.done 
     }; 

     console.log(props); 

     this.props.updateTodo(id, JSON.stringify(props)); 

    } 

    handleDeleteClick(event) { 
     this.props.deleteTodo(this.props.params.id).then(() => { 
      this.context.router.push('/todos_index'); 
     }); 
    } 

    handleSaveClick(event) { 
     var id = this.props.params.id; 
     var props = { 
      title: this.state.newTitle, 
      description: this.state.newDescription 
     }; 
     this.props.updateTodo(id, JSON.stringify(props)).then(() => { 
      this.context.router.push('/todos_index'); 
     }); 
    } 

    handleUndoClick() { 
     this.setState({ 
      descriptionChanged: false, 
      newTitle: this.props.todo.title, 
      newDescription: this.props.todo.description 

     }); 
    } 
} 

function mapStateToProps(state) { 
    return { todo: state.todos.todo }; 
} 

export default connect(mapStateToProps, { fetchTodo, updateTodo, deleteTodo })(ShowTodo); 

回答

2

複選框都應該使用onChange,而不是onClick

編輯:還有另一個問題。

您的組件工作正常。您的調試console.log不是。

this.setState是異步的,所以您不會看到以下代碼行中的更改。如果你想國家已經完成轉換後做一些事情,你應該把它作爲一個回調到setState功能:

this.setState({ 
     descriptionChanged: true, 
     newDescription: event.target.value 
    }, function(){   
      console.log('New description in state: ', this.state.newDescription); 
    } 
}); 
+0

我使用的onChange事先和我有同樣的結果。 – Mjuice

+0

用其他問題編輯。 – gravityplanx

+1

@gravityplanx你只是打敗了我。我認爲出現錯誤的setState在handleDoneChange中,而不是handleDescriptionChange –