在单击反应表上选择行
Posted
技术标签:
【中文标题】在单击反应表上选择行【英文标题】:Select row on click react-table 【发布时间】:2017-12-04 08:23:25 【问题描述】:我正在努力寻找与我的 react 应用程序一起使用的最佳表格,目前,react-table 提供了我需要的一切(分页、服务器端控制、过滤、排序、页脚行)。
话虽如此,我似乎无法选择一行。没有 examples 显示这一点。
我尝试过的一些事情包括尝试在单击该行时设置一个类名。但我似乎无法在e
和t
中找到调用元素。另外,我不喜欢这种方法,因为 React 应用不应该这样做。
<ReactTable
...
getTrProps=(state, rowInfo, column, instance) =>
return
onClick: (e, t) =>
t.srcElement.classList.add('active')
,
style:
/>
一些可能的解决方法是将复选框呈现为第一列,但这不是最佳选择,因为它限制了单击区域以“激活”该行。此外,视觉反馈的表现力也会降低。
我想念房间里的大象吗?如果没有,您知道另一个支持我之前描述的东西的库吗?
谢谢!
编辑: 另一种选择,这是开源的,是建议编辑。也许这是正确的做法。
编辑 2
Davorin Ruševljan 在 cmets 中提出的另一件事是:
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”
【问题讨论】:
【参考方案1】:经过几次尝试,我找到了解决方案,希望对您有所帮助。将以下内容添加到您的 <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
【讨论】:
这个可以多选吗? 也为我工作,但我还必须检查rowinfo !== undefined
以避免运行时错误
@YoungScooter 你用this
影响了that
吗?你更新点击状态了吗?
@ConstantinGuidon 抱歉回复晚了。找到链接了,就在这里! github.com/react-tools/react-table/issues/233
嗨,有人能解释一下我的 rowInfo 是如何被定义为未定义的吗?我不确定如何正确使用getTrProps
方法【参考方案2】:
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 通过这个高阶组件支持选择。【参考方案3】:如果你想在选择行上进行多项选择..
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;
【讨论】:
【参考方案4】:您选择的答案是正确的,但是如果您使用排序表,它将崩溃,因为您搜索时 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'
【讨论】:
【参考方案5】:我不熟悉 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,表将不会重新呈现 你的意思是你没有控制权,你正在为表提供数据属性,在数据中更改它 我的意思是当数据发生变化时,getTrProps 不是页面重新呈现的一部分。不幸的是,将新数据设置到表中并不会调用它。我将按照我尝试的方式编辑我的问题。【参考方案6】:动态样式的另一种机制是在 JSX 中为您的组件定义它。例如,以下内容可用于选择性地设置 React tic-tac-toe 教程中当前步骤的样式(建议的额外信用增强之一:
return (
<li key=move>
<button style=fontWeight:(move === this.state.stepNumber ? 'bold' : '') onClick=() => this.jumpTo(move)>desc</button>
</li>
);
当然,更简洁的方法是添加/删除“选定”的 CSS 类,但这种直接方法在某些情况下可能会有所帮助。
【讨论】:
【参考方案7】:带有复选框的多行并使用useState()
钩子选择所有行。需要少量实现以适应自己的项目。
const data;
const [ allToggled, setAllToggled ] = useState(false);
const [ toggled, setToggled ] = useState(Array.from(new Array(data.length), () => false));
const [ selected, setSelected ] = useState([]);
const handleToggleAll = allToggled =>
let selectAll = !allToggled;
setAllToggled(selectAll);
let toggledCopy = [];
let selectedCopy = [];
data.forEach(function (e, index)
toggledCopy.push(selectAll);
if(selectAll)
selectedCopy.push(index);
);
setToggled(toggledCopy);
setSelected(selectedCopy);
;
const handleToggle = index =>
let toggledCopy = [...toggled];
toggledCopy[index] = !toggledCopy[index];
setToggled(toggledCopy);
if( toggledCopy[index] === false )
setAllToggled(false);
else if (allToggled)
setAllToggled(false);
;
....
Header: state => (
<input
type="checkbox"
checked=allToggled
onChange=() => handleToggleAll(allToggled)
/>
),
Cell: row => (
<input
type="checkbox"
checked=toggled[row.index]
onChange=() => handleToggle(row.index)
/>
),
....
<ReactTable
...
getTrProps=(state, rowInfo, column, instance) =>
if (rowInfo && rowInfo.row)
return
onClick: (e, handleOriginal) =>
let present = selected.indexOf(rowInfo.index);
let selectedCopy = selected;
if (present === -1)
selected.push(rowInfo.index);
setSelected(selected);
if (present > -1)
selectedCopy.splice(present, 1);
setSelected(selectedCopy);
handleToggle(rowInfo.index);
,
style:
background: selected.indexOf(rowInfo.index) > -1 ? '#00afec' : 'white',
color: selected.indexOf(rowInfo.index) > -1 ? 'white' : 'black'
,
else
return
/>
【讨论】:
【参考方案8】:# react-table with edit button #
const [rowIndexState, setRowIndexState] = useState(null);
const [rowBackGroundColor, setRowBackGroundColor] = useState('')
...row.getRowProps(
onClick: (e) =>
if (!e.target.cellIndex)
setRowIndexState(row.index);
setRowBackGroundColor('#f4f4f4')
,
style:
background: row.index === rowIndexState ? rowBackGroundColor : '',
,
)
【讨论】:
以上是关于在单击反应表上选择行的主要内容,如果未能解决你的问题,请参考以下文章
单击 UIButton 以显示 UIPickerView 并在按钮标题上选择 ID:Swift
当单击 dropdownlist.item.insert 作为下拉列表上的空位置时,在下拉列表上选择索引更改时,行/列的数据不存在