我正在使用一个复选框,该复选框应通过组件的状态更新待办事项的已完成状态。当我点击待办事项框时,它不会改变状态,但如果我点击它两次,它会更新状态。由于我必须单击两次,这意味着当选中此框时,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);
答案 0 :(得分: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);
}
});