Table - 删除一些行后,选择了下一行 become/stay

Table - After deleting some rows, the next rows become/stay selected

当我在 table 中删除一些行时,选择了下一行 become/stay。

在我的 state 中,我有 selectedStudentstableDataselectedStudents 都是在我的table.

中选择的索引

当我点击删除按钮时..下面的代码删除了我的 tableData 中的所有行和 selectedStudents.

中的所有值
let diff = _.remove(this.state.tableData, (it, idx) => !~this.state.selectedStudents.indexOf(idx))
this.setState({ tableData: diff, selectedStudents: [] })

问题是删除了行但是后面的行被选中了,不知道为什么

See full image with states details here

这是该组件的完整代码...或 check in WebPack bin

export default React.createClass({

    getInitialState: function() {
        return {
            selectedStudents: [],
            tableData: [
                { name: 'John Smith' },
                { name: 'Randal White' },
                { name: 'Stephanie Sanders' },
                { name: 'Steve Brown' },
                { name: 'Joyce Whitten' },
                { name: 'Samuel Roberts' },
                { name: 'Adam Moore' }
            ]
        }
    },

    // Methods
    _onStudentSelected (selected) {
        let selectedObjs = []
        if (_.isArray(selected)) { // Multiples selections
            selectedObjs.push(...selected)
        } else if (_.isNumber(selected)) { // One Selection
            selectedObjs.push(selected)
        } else if (_.isString(selected) && selected === 'all') { // Select all elements
            selectedObjs.push(...this.state.tableData.map((it, idx) => idx))
        } // None selected

        this.setState({ selectedStudents: selectedObjs })
    },

    _onClickDeleteStudent () {
        let diff = _.remove(this.state.tableData, (it, idx) =>
            !~this.state.selectedStudents.indexOf(idx))

        this.setState({ tableData: diff, selectedStudents: [] })
    },


    render: function() {
        return (
        <Table fixedHeader multiSelectable onRowSelection={this._onStudentSelected}>
            <TableBody deselectOnClickaway={false}>
                {this.state.tableData.map((row, index) => (
                    <TableRow key={row.name} selected={this.state.selectedStudents.indexOf(index) !== -1}>
                        <TableRowColumn>
                            <TextField value={row.name} hintText='Name' />
                        </TableRowColumn>
                        <TableRowColumn>
                            <TextField hintText='Password' type='password' />
                        </TableRowColumn>
                    </TableRow>
                ))}
            </TableBody>
            <TableFooter adjustForCheckbox>
                <TableRow>
                    <TableRowColumn>
                        <RaisedButton label='Delete' onClick={this._onClickDeleteStudent}
                                      disabled={this.state.selectedStudents.length <= 0} />
                    </TableRowColumn>
                </TableRow>
            </TableFooter>
        </Table>
        );
    }
});

版本

包裹 |版本
---------- | ----------------------------------
material-ui | ^0.17.1
反应 | ^15.4.2
浏览器 | Chrome 版本 56.0.2924.87(64 位)

已添加

被报告为 issue 6496

上的错误

这里是您示例的简化现代重构版本:

import React, {Component} from 'react'
import Table from 'material-ui/Table/Table'
import TableBody from 'material-ui/Table/TableBody'
import TableHeader from 'material-ui/Table/TableHeader'
import TableFooter from 'material-ui/Table/TableFooter'
import TableHeaderColumn from 'material-ui/Table/TableHeaderColumn'
import TableRow from 'material-ui/Table/TableRow'
import TableRowColumn from 'material-ui/Table/TableRowColumn'
import TextField from 'material-ui/TextField/TextField'
import RaisedButton from 'material-ui/RaisedButton/RaisedButton'

export default class MyTable extends Component {

  state = {
    selectedStudents: [],
    tableData: [
      { id: 0, name: 'John Smith' },
      { id: 1, name: 'Randal White' },
      { id: 2, name: 'Stephanie Sanders' },
      { id: 3, name: 'Steve Brown' },
      { id: 4, name: 'Joyce Whitten' },
      { id: 5, name: 'Samuel Roberts' },
      { id: 6, name: 'Adam Moore' }
    ]
  }

  // Methods
  _onStudentSelected = (selected) => {
    let selectedStudents = selected === 'all'// Select all elements
      ? [...this.state.tableData].map(({id}) => id)
      : selected

    console.log('selected', selected,
                '\nSelected students', selectedStudents)

    this.setState({selectedStudents})
  }

  _onClickDeleteStudent = () => {
    let tableData = this.state.tableData.filter(({id}) =>
      !this.state.selectedStudents.includes(id)
    )

    this.setState({tableData, selectedStudents: []}, () => {
      console.log('After delete', this.state.tableData,
                '\nthis.state.selectedStudents', this.state.selectedStudents)
    })
  }

  render () {
    console.debug('rendered selectedStudents', this.state.selectedStudents)
    const isSelected = id => {
      let result = this.state.selectedStudents.includes(id)
      console.log('id', id, 'result', result)
      return result
    }
    return (
      <Table fixedHeader multiSelectable enableSelectAll onRowSelection={this._onStudentSelected}>
        <TableHeader>
          <TableRow>
            <TableHeaderColumn>Name</TableHeaderColumn>
            <TableHeaderColumn>Password</TableHeaderColumn>
          </TableRow>
        </TableHeader>
        <TableBody deselectOnClickaway={false}>
          {this.state.tableData.map(({id, name}) => (
            <TableRow key={id} selected={isSelected(id)}>
              <TableRowColumn>
                <TextField value={name} hintText='Name' />
              </TableRowColumn>
              <TableRowColumn>
                <TextField hintText='Password' type='password' />
              </TableRowColumn>
            </TableRow>
          ))}
        </TableBody>
        <TableFooter adjustForCheckbox>
          <TableRow>
            <TableRowColumn>
              <RaisedButton label='Delete' onTouchTap={this._onClickDeleteStudent}
                            disabled={!this.state.selectedStudents.length} />
            </TableRowColumn>
          </TableRow>
        </TableFooter>
      </Table>
    )
  }
}

尽管没有解决您的问题,但希望对您有所帮助。您应该在 Material-UI 回购中提出问题。

请使用 onTouchTap 而不是 onClick

在当前的稳定版本16.7中,Table组件的onRowSelection(indices),indices在删除最后一行后并没有反映正确的状态。您可以通过 npm install --save material-ui@next 查看固定版本,但目前仍在测试中。干杯。

已编辑: M.Quan 更改了源代码,顺便说一句,它对我来说没问题。 请参阅 https://github.com/callemall/material-ui/issues/6006

"我在第131行找到错误原因 https://github.com/callemall/material-ui/blob/master/src/Table/TableBody.js

componentWillReceiveProps(nextProps) {
    if (this.props.allRowsSelected !== nextProps.allRowsSelected) {
        if (!nextProps.allRowsSelected) {
            this.setState({
              selectedRows: [],
            });
        } else {
            this.setState({
                selectedRows: this.calculatePreselectedRows(nextProps),
            });
        }
    }
}

当我用版本 0.16.6 中的代码更改该代码时。它对我有用!

componentWillReceiveProps(nextProps) {
    if (this.props.allRowsSelected && !nextProps.allRowsSelected) {
        this.setState({
            selectedRows: this.state.selectedRows.length > 0 ?
            [this.state.selectedRows[this.state.selectedRows.length - 1]] : [],
        });
        // TODO: should else be conditional, not run any time props other than allRowsSelected change?
    } else {
        this.setState({
            selectedRows: this.calculatePreselectedRows(nextProps),
        });
    }
} 

"