在我的应用程序中,单击列表项或复选框时会调用函数'todoCompleted'。当我单击复选框时,代码未正确运行。该功能用于li元素和复选框字段。
class App extends React.Component {
constructor(){
super();
this.state={
todo:[]
};
};
entertodo(keypress){
var Todo=this.refs.inputodo.value;
if( keypress.charCode == 13 )
{
this.setState({
todo: this.state.todo.concat({Value:Todo, checked:false})
});
this.refs.inputodo.value=null;
};
};
todo(todo,i){
return (
<li className={todo.checked===true? 'line':'newtodo'}>
<div onClick={this.todoCompleted.bind(this,i)}>
<input type="checkbox" className="option-input checkbox" checked={todo.checked} />
<div key={todo.id} className="item">
{todo.Value}
<div className="Button">
<span className="destroy" onClick={this.remove.bind(this, i)}>X</span>
</div>
</div>
</div>
</li>
);
};
remove(i){
this.state.todo.splice(i,1)
this.setState({todo:this.state.todo})
};
todoCompleted(i){
var todo=this.state.todo;
{
todo[i].checked =true;
this.setState({
todo:this.state.todo
});
}
};
allCompleted=()=>{
var todo = this.state.todo;
var _this = this
todo.forEach(function(item) {
item.className = _this.state.finished ? "newtodo" : "line"
item.checked = !_this.state.finished
})
this.setState({todo: todo, finished: !this.state.finished})
};
render() {
return (
<div>
<h1 id='heading'>todos</h1>
<div className="lines"></div>
<div>
<input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/>
<span onClick={this.allCompleted}id="all">x</span>
</div>
<div className="mainapp">
<ul>
{this.state.todo.map(this.todo.bind(this))}
</ul>
</div>
</div>
);
}
}
ReactDOM.render(<App/>,document.getElementById('app'));
.line {
text-decoration: line-through;
color: red;
}
.newtodo{
text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>
答案 0 :(得分:1)
单击todoCompleted
元素时,会调用input
方法2次。对于每个li
元素,它也会绑定3次:li
,input
和button
点击。作为快速修复,您可以通过以下方式重新格式化li
元素的结构:
在这里演示:http://codepen.io/PiotrBerebecki/pen/bwmwqz
<li className={text.Decor}>
<div onClick={this.todoCompleted.bind(this,i)}>
<input type="checkbox"
className="option-input checkbox"
checked={text.checked} />
<div key={text.id}
className="item">
{text.Value}
</div>
</div>
<button type="button"
className="destroy"
onClick={this.remove.bind(this,i)}>
X
</button>
</li>
请注意
i
现已传递到remove
方法,以及todoCompleted
方法仅绑定一次。出于性能原因,在渲染JSX时应避免使用bind或箭头函数。这是因为为map()函数生成的每个实例都创建了事件处理函数的副本。这在此解释:https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md 你也一直在改变状态:
remove(i){
this.state.todo.splice(i,1)
this.setState({todo:this.state.todo})
};
以上内容你可以:
remove(i){
this.setState({
todo: [
...this.state.todo.slice(0, i),
...this.state.todo.slice(i + 1)
]
});
};
答案 1 :(得分:0)
看起来你的this.todoCompleted
在这里被解雇了两次(简化你的html):
<li onClick={this.todoCompleted.bind(this,i)}>
<input type="checkbox" onChange={this.todoCompleted.bind(this,i)} checked={text.checked} />
</li>
首先,li
上的那个被解雇了。它设置复选框以纠正它应该的状态。但是,实际复选框上的那个被解雇了!并将待办事项设置回未经检查的状态。所以看起来它不起作用:)。
如果您将复选框移出li
元素,就像我在此处所做的那样,您可以很容易地看到它:http://www.webpackbin.com/Nk9NTh0RZ