在React JS中单击按钮将LI元素设置为非活动状态

时间:2016-12-16 13:09:04

标签: javascript reactjs

好的,所以这是一个菜鸟问题,答案可能就在我的鼻子底下,但我似乎无法弄清楚如何做到这一点。基本上,我在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">&#x2714;</button>
          <button id="remove" onClick={this.delete} className="btn btn-danger btn-xs">&#x2718;</button>
        </div>
      </li>
    );
  }
});

var App = React.createClass({
  render: function() {
    return (
      <div id="main" className="page-wrap">
        <ListContainer />
      </div>
    );
  }
});

ReactDOM.render(
  <App/>,
  document.getElementById('app')
);

提前感谢您的帮助!

1 个答案:

答案 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}}