我使用Rails和React-Table来显示表格,目前它运行良好。但是如何在React-Table中添加一个编辑/删除列呢?
这是否可能?
return (
<ReactTable
data={this.props.working_hours}
columns={columns}
defaultPageSize={50}
className="-striped -highlight"
/>
)
我使用Rails和React-Table来显示表格,目前它运行良好。但是如何在React-Table中添加一个编辑/删除列呢?
这是否可能?
return (
<ReactTable
data={this.props.working_hours}
columns={columns}
defaultPageSize={50}
className="-striped -highlight"
/>
)
你需要做的就是将 columns
转化为组件状态。你可以在这个示例中看到一个工作的例子:https://codesandbox.io/s/0pp97jnrvv
[更新于 2018 年 3 月 5 日] 之前理解错了问题,这是更新后的答案:
const columns = [
...
{
Header: '',
Cell: row => (
<div>
<button onClick={() => handleEdit(row.original)}>Edit</button>
<button onClick={() => handleDelete(row.original)}>Delete</button>
</div>
)
}
]
其中handleEdit
和handleDelete
将是回调函数,您可以在这些函数中定义按钮被点击后的操作方式。
Cell: ({row}) => (
- Alasdair ShieldsCell: ({row}) => (
! - Ayoub Laazazi在表格中添加列可以通过将列对象插入到传递给useTable钩子的列定义中来实现。基本上,驻留在列定义数组中的列对象数量表示由react-table呈现的列数。
通常,最小的列对象包括Header和accessor,其中在Header中我们传递列的名称,在accessor中,我们传递react-table将用于从传递给useTable钩子的数据中查找值的键。
{
Header: "Column Name",
accessor: "data key", // can be a nested key
}
在这里,要在单元格内呈现除字符串以外的其他内容,即自定义按钮JSX,我们可以使用accessor或Cell选项,并将其传递给一个返回有效JSX的Function。
文档中提到accessor接受string或Function。在这里,我们使用Function来呈现JSX按钮。
accessor: String | Function(originalRow, rowIndex) => any
使用访问器选项的好处之一是rowIndex
直接可用。 rowIndex表示当前由客户端管理的数据数组中行的索引号,而originalRow是row的原始对象。
在这里,rowIndex
可以用作引用,以选择和修改列数据数组中的行对象。
Cell选项接受返回JSX或React.Component的函数。 Cell选项通常用于格式化单元格值,但在这里我们用于呈现我们的按钮。
Cell: Function | React.Component => JSX
函数接收一个名为tableInstance的参数,该参数与使用useTable钩子的结果非常相似,但还包含了cell、row和column对象。
Cell: (tableInstance) => JSX
我们还可以通过解构行对象来获取行索引信息:
Cell: (tableInstance) => {
const { row: index } = tableInstance;
return (
...
)
}
現在,我們已經有了列。下一步是按鈕。通常按鈕是普通按鈕,可以調用處理程序來更新狀態或觸發對話框彈出窗口,或者是鏈接按鈕,可以將應用程序重定向到詳細頁面。如果 accessor 是一個函數,則必須提供此選項。 此選項標識列的唯一 ID。在排序、分組、過濾等操作中,它被引用。
// accessor
{
Header: 'Action',
id: 'action',
accessor: (originalRow, rowIndex) => {
return (
// you can pass any information you need as argument
<button onClick={() => onClickHandler(args)}>
X
</button>
)
}
}
// or Cell
{
Header: 'Action',
accessor: "action",
Cell: (tableInstance) => {
const { row: index } = tableInstance;
return (
// you can pass any information you need as argument
<button onClick={() => onClickHandler(args)}>
X
</button>
)
}
}
例子:
const { useCallback, useEffect, useMemo, useState } = React;
const { useTable } = ReactTable;
// table data
const data = [
{
name: "John",
workingHours: 40
},
{
name: "Doe",
workingHours: 40
}
];
const AddEmployee = ({ onSubmit }) => {
const [name, setName] = useState("");
const [workingHours, setWorkingHours] = useState("");
const handleSubmit = (e) => {
onSubmit(e);
setName("");
setWorkingHours("");
}
return (
<fieldset style={{ width: "200px" }}>
<legend>Add Employee:</legend>
<form onSubmit={(e) => handleSubmit(e)}>
<input
type="text"
name="name"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<br />
<input
type="text"
name="workingHours"
placeholder="Working Hours"
value={workingHours}
onChange={(e) => setWorkingHours(e.target.value)}
/>
<br />
<button type="submit">Add</button>
</form>
</fieldset>
)
}
const EditEmployee = ({ row, onSave }) => {
const { originalRow, rowIndex } = row;
const [name, setName] = useState(originalRow.name);
const [workingHours, setWorkingHours] = useState(originalRow.workingHours);
return (
<fieldset style={{ width: "200px" }}>
<legend>Edit Employee:</legend>
<input
type="text"
name="name"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<br />
<input
type="text"
name="workingHours"
placeholder="Working Hours"
value={workingHours}
onChange={(e) => setWorkingHours(e.target.value)}
/>
<br />
<button onClick={() => onSave({ name, workingHours }, rowIndex)}>Save</button>
</fieldset>
)
}
function App() {
const [tableData, setTableData] = useState(data);
const [editingRow, setEditingRow] = useState();
const handleDelete = useCallback((index) => {
setTableData(tableData.filter((v, i) => i !== index));
},[tableData]);
const tableColumns = useMemo(() => [
{
Header: 'Name',
accessor: 'name',
},
{
Header: 'Working Hours',
accessor: 'workingHours'
},
{
Header: 'Action',
id: 'action',
accessor: (originalRow, rowIndex) => {
return (
<div>
<button onClick={() => setEditingRow({ originalRow, rowIndex })}>
Edit
</button>
<button onClick={() => handleDelete(rowIndex)}>
Delete
</button>
</div>
)
}
}
], [handleDelete]);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable({
columns: tableColumns,
data: tableData,
});
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const newData = {};
formData.forEach((value, key) => newData[key] = value);
setTableData((prevData) => {
return [...prevData, newData];
});
};
const handleEdit = useCallback((row, rowIndex) => {
const editedData = tableData.map((rowData, index) => {
if (index === rowIndex) {
return row;
}
return rowData;
});
setTableData(editedData);
setEditingRow();
},[tableData])
return (
<div>
<h3>React-table v.7</h3>
<br />
{ editingRow ? <EditEmployee row={editingRow} onSave={handleEdit} /> : <AddEmployee onSubmit={handleSubmit} /> }
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()}>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
</div>
)
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-table@7.8.0/dist/react-table.development.js"></script>
<div class='react'></div>
{
Header: 'Action',
accessor: (originalRow, rowIndex) => (
<div>
<button onClick={() => handleEdit(originalRow)}>Edit</button>
<button onClick={() => handleDelete(originalRow)}>Delete</button>
</div>
),
id: 'action',
},