单击react表选择行

IT技术 reactjs react-table
2021-04-11 12:19:57

我正在尝试找到与我的 React 应用程序一起使用的最佳表格,目前,react-table提供了我需要的一切(分页、服务器端控制、过滤、排序、页脚行)。

话虽如此,我似乎无法选择一行。没有例子可以说明这一点。

我尝试过的一些事情包括尝试在单击行时设置 className。但我似乎无法在enor 中找到调用元素t另外,我不喜欢这种方法,因为它不是 React 应用程序应该做的事情。

<ReactTable
            ...
            getTrProps={(state, rowInfo, column, instance) => {
                return {
                    onClick: (e, t) => {
                        t.srcElement.classList.add('active')
                    },
                    style: {
                    }
                }
            }}
        />

一些可能的解决方法是将复选框呈现为第一列,但这不是最佳选择,因为它限制了单击以“激活”行的区域。此外,视觉反馈将缺乏表现力。

我想念房间里的大象吗?如果没有,你知道另一个支持我之前描述的东西的库吗?

谢谢!

编辑: 另一个选项,这是开源的,是建议编辑。也许这是正确的做法。

编辑 2

另一件事,由 Davorin Ruševljan 在评论中提出,但我无法让它发挥作用:

onRowClick(e, t, rowInfo) {
    this.setState((oldState) => {
        let data = oldState.data.slice();
        let copy = Object.assign({},  data[rowInfo.index]);

        copy.selected = true;
        copy.FirstName = "selected";
        data[rowInfo.index] = copy;

        return {
            data: data,
        }
    })
}

....

            getTrProps={(state, rowInfo, column) => {
                return {
                    onClick: (e, t) => { this.onRowClick(e, t, rowInfo) },
                    style: {
                        background: rowInfo && rowInfo.row.selected ? 'green' : 'red'
                    }
                }
            }}

这会将“FirstName”列设置为“selected”,但不会将类设置为“green”

6个回答

经过几次尝试,我找到了解决方案,希望对您有所帮助。将以下内容添加到您的<ReactTable>组件中:

getTrProps={(state, rowInfo) => {
  if (rowInfo && rowInfo.row) {
    return {
      onClick: (e) => {
        this.setState({
          selected: rowInfo.index
        })
      },
      style: {
        background: rowInfo.index === this.state.selected ? '#00afec' : 'white',
        color: rowInfo.index === this.state.selected ? 'white' : 'black'
      }
    }
  }else{
    return {}
  }
}

在你state不要忘记添加一个空selected值,如:

state = { selected: null }
@ConstantinGuidon 抱歉回复晚了。找到了链接,在这里!github.com/react-tools/react-table/issues/233
2021-05-29 12:19:57
这可以做多选吗?
2021-06-09 12:19:57
也为我工作,但我也必须检查 rowinfo !== undefined以避免运行时错误
2021-06-11 12:19:57
@YoungScooter 你影响thatthis吗?您是否在单击时更新了状态?
2021-06-21 12:19:57
嗨,有人可以解释为什么我的 rowInfo 是未定义的吗?我不确定如何getTrProps正确使用该方法
2021-06-21 12:19:57

React-Table 包含一个 HOC,允许进行选择,即使在过滤和分页表格时,设置也比基本表格稍微先进,因此请先阅读下面链接中的信息。


在此处输入图片说明



导入 HOC 后,您可以像这样使用必要的方法来使用它:

/**
* Toggle a single checkbox for select table
*/
toggleSelection(key: number, shift: string, row: string) {
    // start off with the existing state
    let selection = [...this.state.selection];
    const keyIndex = selection.indexOf(key);

    // check to see if the key exists
    if (keyIndex >= 0) {
        // it does exist so we will remove it using destructing
        selection = [
            ...selection.slice(0, keyIndex),
            ...selection.slice(keyIndex + 1)
        ];
    } else {
        // it does not exist so add it
        selection.push(key);
    }
    // update the state
    this.setState({ selection });
}

/**
* Toggle all checkboxes for select table
*/
toggleAll() {
    const selectAll = !this.state.selectAll;
    const selection = [];

    if (selectAll) {
        // we need to get at the internals of ReactTable
        const wrappedInstance = this.checkboxTable.getWrappedInstance();
        // the 'sortedData' property contains the currently accessible records based on the filter and sort
        const currentRecords = wrappedInstance.getResolvedState().sortedData;
        // we just push all the IDs onto the selection array
        currentRecords.forEach(item => {
            selection.push(item._original._id);
        });
    }
    this.setState({ selectAll, selection });
}

/**
* Whether or not a row is selected for select table
*/
isSelected(key: number) {
    return this.state.selection.includes(key);
}

<CheckboxTable
    ref={r => (this.checkboxTable = r)}
    toggleSelection={this.toggleSelection}
    selectAll={this.state.selectAll}
    toggleAll={this.toggleAll}
    selectType="checkbox"
    isSelected={this.isSelected}
    data={data}
    columns={columns}
/>

有关更多信息,请参见此处:https :
//github.com/tannerlinsley/react-table/tree/v6#selecttable

这是一个工作示例:https :
//codesandbox.io/s/react-table-select-j9jvw

这似乎是最好的方法。react-table 通过这个高阶组件支持选择。
2021-06-21 12:19:57

如果您想在选择行上进行多项选择..

import React from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { ReactTableDefaults } from 'react-table';
import matchSorter from 'match-sorter';


class ThreatReportTable extends React.Component{

constructor(props){
  super(props);

  this.state = {
    selected: [],
    row: []
  }
}
render(){

  const columns = this.props.label;

  const data = this.props.data;

  Object.assign(ReactTableDefaults, {
    defaultPageSize: 10,
    pageText: false,
    previousText: '<',
    nextText: '>',
    showPageJump: false,
    showPagination: true,
    defaultSortMethod: (a, b, desc) => {
    return b - a;
  },


  })

    return(
    <ReactTable className='threatReportTable'
        data= {data}
        columns={columns}
        getTrProps={(state, rowInfo, column) => {


        return {
          onClick: (e) => {


            var a = this.state.selected.indexOf(rowInfo.index);


            if (a == -1) {
              // this.setState({selected: array.concat(this.state.selected, [rowInfo.index])});
              this.setState({selected: [...this.state.selected, rowInfo.index]});
              // Pass props to the React component

            }

            var array = this.state.selected;

            if(a != -1){
              array.splice(a, 1);
              this.setState({selected: array});


            }
          },
          // #393740 - Lighter, selected row
          // #302f36 - Darker, not selected row
          style: {background: this.state.selected.indexOf(rowInfo.index) != -1 ? '#393740': '#302f36'},


        }


        }}
        noDataText = "No available threats"
        />

    )
}
}


  export default ThreatReportTable;

您选择的答案是正确的,但是如果您使用排序表,它会崩溃,因为在您搜索时 rowInfo 将变为未定义,建议改用此函数

                getTrGroupProps={(state, rowInfo, column, instance) => {
                    if (rowInfo !== undefined) {
                        return {
                            onClick: (e, handleOriginal) => {
                              console.log('It was in this row:', rowInfo)
                              this.setState({
                                  firstNameState: rowInfo.row.firstName,
                                  lastNameState: rowInfo.row.lastName,
                                  selectedIndex: rowInfo.original.id
                              })
                            },
                            style: {
                                cursor: 'pointer',
                                background: rowInfo.original.id === this.state.selectedIndex ? '#00afec' : 'white',
                                color: rowInfo.original.id === this.state.selectedIndex ? 'white' : 'black'
                            }
                        }
                    }}
                }

我不熟悉 react-table,所以我不知道它对选择和取消选择有直接的支持(如果有就太好了)。

如果没有,您可以使用已有的代码安装 onCLick 处理程序。现在,您可以修改状态,例如将 selected: true 添加到行数据,而不是尝试将样式直接附加到行。那会触发重新渲染。现在您只需要覆盖 selected === true 的行是如何呈现的。类似的东西:

// Any Tr element will be green if its (row.age > 20) 
<ReactTable
  getTrProps={(state, rowInfo, column) => {
    return {
      style: {
        background: rowInfo.row.selected ? 'green' : 'red'
      }
    }
  }}
/>
感谢您的重播,@Davorin!我认为这没有任何用处,因为我无法控制表的状态,因此我无法设置 rowInfo.row.selected .. 不调用 this.setState,表将不会重新渲染
2021-05-29 12:19:57
你是什​​么意思你没有控制权,你正在提供具有数据属性的表,在数据中更改它
2021-05-30 12:19:57
我的意思是当数据更改时,getTrProps 不是页面重新呈现的一部分。不幸的是,将新数据设置到表不会调用它。我将按照我尝试的方式编辑我的问题。
2021-06-04 12:19:57