首页 > 解决方案 > React:将按钮的状态设置为禁用使得无法勾选复选框

问题描述

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

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

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

我正在使用 javascript Set 来跟踪任何勾选的复选框。

编辑:你可以在这里看到一个演示:

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 的状态和复选框的状态之间我看不到任何依赖关系,这怎么会发生?

标签: javascriptreactjs

解决方案


您的代码中的问题是您将整个数组存储在this变量中,将其存储在state变量中,因为更新此不会重新渲染组件,但是如果您将其存储在状态中并使用this.setState()该组件进行更新将得到渲染,您可以看到更新 UI。

问题 2:您的checkedinstate不是每行或每 id。它是用于所有行的单一变量。

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


推荐阅读