通过回调将按钮向下传递到组件

时间:2019-01-29 23:04:33

标签: reactjs

如果我有一个表,该表由行组成,并且我的该表的容器希望将按钮向下传递给该表但自己处理点击,该怎么办?请参阅下面的未经测试的代码来说明情况。如果执行此操作,将不会起作用,因为data-employee显然将变为[object Object]。我该如何传递按钮,又要确保EmployeeTable能够将员工附加到按钮上?


class TableContainer extends React.Component {

  constructor(props) {
    super(props);
  }

  rowButtonClick(e) {
    // Get the employee from onClick event somehow
  }

  render () {

    let rowButtons = [
      employee => (<button onClick={this.rowButtonClick} data-employee={employee}>View</button>),
      employee => (<button onClick={this.rowButtonClick} data-employee={employee}>Delete</button>)
    ]

    return (
      <EmployeeTable rowButtons={rowButtons} />
    );
  }
}

class EmployeeTable extends React.Component {

  /** Fetches it's own employees in state **/

  render () {
    return (
      <table>
        {this.state.employees.map((employee, key) => {
        <tr>
          <td>{employee.name}</td>
          <td>
            {this.props.employeeButtons.map((btn, key) => {
              return btn(employee);
            })}
          </td>
        </tr>
        })}
      </table>
    )
  }
}

3 个答案:

答案 0 :(得分:0)

您不需要像这样传递按钮数组。

重构

//***************************************************/

class TableContainer extends React.Component {

  viewEmployee(employee) {
      console.log('Called view on:', employee.name)
  }

  deleteEmployee(employee) {
      console.log('Called delete on:', employee.name)
  }

  render () {

    return (
      <EmployeeTable 
        viewEmployee={(employee) => this.viewEmployee(employee)}
        deleteEmployee={(employee) => this.deleteEmployee(employee)} 
      />
    );
  }
}

//***************************************************/

class EmployeeTable extends React.Component {

  /** Fetches it's own employees in state **/

  render () {
    return (
      <table>
        {this.state.employees.map(employee => {
          <tr>
            <td>{employee.name}</td>
            <td>
              <button onClick={() => this.props.viewEmployee(employee)}>View</button>
              <button onClick={() => this.props.deleteEmployee(employee)}>Delete</button>
            </td>
          </tr>
        })}
      </table>
    )
  }
}

//***************************************************/

答案 1 :(得分:0)

您可以使用闭包来解决问题。

class TableContainer extends React.Component {

  constructor(props) {
    super(props);
  }

  rowButtonClick(employee) {
    return (event) => {
      //Add employee handling here.
    };
  }

  render () {

    let rowButtons = [
      employee => (<button onClick={this.rowButtonClick(employee)} data-employee={employee}>View</button>),
      employee => (<button onClick={this.rowButtonClick(employee)} data-employee={employee}>Delete</button>)
    ]

    return (
      <EmployeeTable rowButtons={rowButtons} />
    );
  }
}

这将确保内部功能始终可以使用员工信息。

答案 2 :(得分:-1)

将按钮作为组件传递,以接收代表点击事件的道具和代表该点击数据的另一个道具。

说:

const EmployeeTableButton = (props) => {
    return <button onClick={() => props.rowButtonClick(props.employee)}>{props.actionName}</button>)
}

class TableContainer extends React.Component {

  rowButtonClick = (action) => (employee) {
    // get the wanted action from the pre scoped action param
    // then execute it with the employee param passed by the renderer 
  }

  render () {

    let rowButtons = [
      {
          actionName: 'View',
          rowButtonClick: this.rowButtonClick('view')
      },
      {
          actionName: 'Delete',
          rowButtonClick: this.rowButtonClick('delete')
      }
    ]

    return (
      <EmployeeTable rowButtons={rowButtons} />
    );
  }
}

class EmployeeTable extends React.Component {

  render () {
    return (
      <table>
        {this.state.employees.map((employee, key) => {
        <tr>
          <td>{employee.name}</td>
          <td>
            {
                this.props.employeeButtons.map((btn) => (
                   <EmployeeTableButton {...btn} employee={employee} />
                ) 
            }
          </td>
        </tr>
        })}
      </table>
    )
  }
}