反应:将按钮的状态设置为“禁用”使得无法勾选复选框

时间:2018-06-21 07:40:33

标签: javascript reactjs

我有一个包含三个组件的应用程序:

  1. HTML表
  2. 包含复选框的表行
  3. 一个按钮

如果所有复选框均未选中,我希望禁用该按钮。如果勾选了一个或多个复选框,则应启用它。

我正在使用JavaScript集来跟踪所有已打勾的复选框。

编辑:您可以在此处查看演示:

https://codesandbox.io/s/w2rlywxzol

表格行具有以下代码:

class EventRowAdmin extends Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      isChecked: false
    }
  }

  handleChange(e) {
    const target = e.target;
    console.log('target checked' + target.checked);
    this.setState({
      isChecked: target.checked
    });
    this.props.manageCheckboxes(this.props.id);
  }

  render() {
    return (
      <tr id={this.props.id}>
        <td><input type="checkbox" checked={this.state.isChecked} onChange={this.handleChange} className="remove-event"/></td>
        <td>{this.props.date}</td>
        <td>{this.props.name}</td>
        <td>{this.props.location}</td>
        <td>{this.props.ticketLink}</td>
      </tr>
    )
  }
}

该表包含以下用于管理复选框的代码:

class EventsTableAdmin extends Component {

  ...

  componentWillMount() {
    this.selectedCheckboxes = new Set();
  }
  manageCheckboxes(id) {
    console.log('id is:' + id);
    if (this.selectedCheckboxes.has(id)) {
      this.selectedCheckboxes.delete(id);
    } else {
      this.selectedCheckboxes.add(id);
    }

    if(this.selectedCheckboxes.size > 0) {
      this.setState({ deleteButtonDisabled: false});
    }
    else {
      this.setState({ deleteButtonDisabled: true});
    }
  }

  makeEventsTable() {
    const events = this.props.data;
    const eventsRows = events.map((event, i) => {
      let key = `event-${Date.now()}-${i}`;
      let id = i;
      return (
        <EventRowAdmin manageCheckboxes={this.manageCheckboxes} key={key} id={id} date={event.date} name={event.name} location={event.location} ticketLink={event.ticketLink} />
      );
    });
    return eventsRows;
  }

  render() {
    <ButtonDeleteEvents isDisabled={this.state.deleteButtonDisabled} handleDeleteEvents={this.handleDeleteEvents} />
    <table className="table table-events table-striped">
      <thead>
        <tr><th></th>
        <th>Date</th>
        <th>Event</th>
        <th>Location</th>
        <th>Ticket Link</th>
      </tr>
    </thead>
    <tbody>
      {this.makeEventsTable() }
    </tbody>
  </table>

}

该按钮具有以下代码:

class ButtonDeleteEvents extends Component {
  constructor() {
    super();
  }

  render() {
    return (
      <button disabled={this.props.isDisabled} onClick={this.props.handleDeleteEvents} className="btn secondary">Delete Selected Events</button>
    )
  }

}

EventsTableAdmin组件中的关键代码如下:

if(this.selectedCheckboxes.size > 0) {
  this.setState({ deleteButtonDisabled: false});
}
else {
  this.setState({ deleteButtonDisabled: true});
}

如果删除此代码,则可以选中复选框。但是,如果有代码,则无法勾选复选框。

这怎么可能发生,因为在deleteButtonDisabled的状态和复选框的状态之间没有依存关系?

2 个答案:

答案 0 :(得分:1)

代码中的问题是,您将整个数组存储在this变量中,并将其存储在state变量中,因为更新了此未重新渲染的组件,但是如果将其存储在状态中并使用{ {1}}组件将获得渲染,您可以看到更新UI。

问题2 :您在this.setState()中的checked不是按行还是按ID。它是用于所有行的信号变量。

外观问题已解决:https://codesandbox.io/s/6wnxj77qjn

答案 1 :(得分:0)

当您在第67行上更改EventsTableAdmin的状态时,绑定到该Component的所有组件将被强制重新呈现。因此,在EventRowAdmin的构造函数中,您已经将isChecked的值设置为false,因此,每次组件重新渲染时,复选框状态都会重置为false。