好的,所以这是一个菜鸟问题,答案可能就在我的鼻子底下,但我似乎无法弄清楚如何做到这一点。基本上,我在React中创建了一个待办事项列表,并希望用户将项目标记为已完成。
我已经尝试通过父容器的状态设置它,然后通过元素道具访问该状态,但它不起作用。
到目前为止,这是我的代码。请参阅getInitialState函数,onCompleted,ListContainer的return函数和Item。
var ListContainer = React.createClass({
getInitialState: function() {
return {
numChildren: 0,
list: [],
disabled: false
};
},
onAddChild: function() {
var inputValue = document.getElementById('itemAdder').value;
var ul = document.getElementById('list');
var newList = this.state.list;
if(inputValue !== '') {
newList.push(inputValue);
ul.style.display = 'block';
}
this.setState({
numChildren: this.state.numChildren + 1,
list: newList
});
},
onDeleteChild: function(index) {
this.state.list.splice(index, 1);
this.setState({
list: this.state.list
});
},
onCompleted: function() {
this.setState({
disabled: true
});
},
render: function() {
var children = [];
for (var i = 0; i < this.state.list.length; i++) {
children.push(<Item key={'item_' + i} number={i} onDeleteChild={this.onDeleteChild} completed={this.state.onCompleted} content={this.state.list[i]}/>);
};
return (
<List addChild={this.onAddChild}>
{children}
</List>
);
}
});
var List = React.createClass({
render: function() {
return (
<div id="listContainer">
<h1 className="no-margins even-padding page-header ">To do list</h1>
<div className="even-padding form-inline">
<input type="text" name="itemAdder" id="itemAdder" className="form-control" placeholder="Enter things that need doing..." />
<button type="button" className="btn btn-primary" onClick={this.props.addChild}>Add item</button>
<ul id="list" className="no-margins list">
{this.props.children}
</ul>
</div>
</div>
);
}
});
var Item = React.createClass({
complete: function() {
this.props.completed;
},
delete: function() {
this.props.onDeleteChild(this.props.number);
},
render: function() {
return (
<li className="clearfix">
{this.props.content}
<div className="pull-right">
<button onClick={this.complete} id="completed" className="btn btn-success btn-xs">✔</button>
<button id="remove" onClick={this.delete} className="btn btn-danger btn-xs">✘</button>
</div>
</li>
);
}
});
var App = React.createClass({
render: function() {
return (
<div id="main" className="page-wrap">
<ListContainer />
</div>
);
}
});
ReactDOM.render(
<App/>,
document.getElementById('app')
);
提前感谢您的帮助!
答案 0 :(得分:1)
首先,for循环中的子列表不正确。完成的道具应该像这样通过:
onAddChild: function() {
var inputValue = document.getElementById('itemAdder').value;
var ul = document.getElementById('list');
var newList = this.state.list;
if(inputValue !== '') {
newList.push({value: inputValue, disabled: false});
ul.style.display = 'block';
}
this.setState({
numChildren: this.state.numChildren + 1,
list: newList
});
你所构建的状态也有不正确的结构。列表中的每个项目都应禁用其自己的属性。如果您不这样做,则所有项目都将被禁用或所有项目都将启用。
要解决此问题,请从getInitialState的return语句中删除disabled属性并更改onAddChild方法
for (var i = 0; i < this.state.list.length; i++) {
children.push(<Item key={'item_' + i} number={i} onDeleteChild={this.onDeleteChild} completed={this.onCompleted} content={this.state.list[i].value}/>);
};
}
现在更改您的孩子列表:
onCompleted: function(itemIndex) {
var newList = this.state.list.slice();
newList[itemIndex].disabled = true;
this.setState({
list: newList
});
}
现在你的onCompleted方法必须传递必须更新的项目的索引
complete: function() {
this.props.completed(this.props.number) // Passing the index of the item as an argument
}
最后,必须更新Item组件的render方法。只需在第一个按钮的onCLick被触发时传递列表项的索引,即更改List Component中的完整方法,如下所示:
{{1}}