我正在使用 Prime React 表来渲染 React 中的动态数据。我在 datatable 文档的帮助下构建了我的组件。
当我单击“添加行”按钮时,我希望用户可以立即编辑新添加的行(最好使用我稍后添加的键盘焦点),而无需他们使用编辑按钮来编辑空的新行。这可能吗?
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { data } from "../data";
import { useState } from "react";
import { InputText } from "primereact/inputtext";
export const Table = () => {
const [users, setUsers] = useState(data);
const handleAddRow = (): void => {
const newRow: any = {
firstName: "",
lastName: "",
email: "",
phone: "",
freeTextField: "",
};
setUsers((prevList: any) => [newRow, ...prevList]);
};
const onRowEditComplete = (e: any) => {
const _users = [...users];
const { newData, index } = e;
_users[index] = newData;
setUsers(_users);
};
const textEditor = (options: any) => {
return (
<InputText
type="text"
value={options.value}
onChange={(e) => options.editorCallback(e.target.value)}
/>
);
};
return (
<div className="table-wrapper">
<h2 className="table-name">PrimeReact data table</h2>
<button onClick={handleAddRow}>add row</button>
<DataTable
value={users}
tableStyle={{ minWidth: "50rem" }}
editMode="row"
onRowEditComplete={onRowEditComplete}
>
<Column
field="firstName"
header="firstName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="lastName"
header="lastName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="email"
header="email"
editor={(options) => textEditor(options)}
></Column>
<Column
field="phone"
header="phone"
editor={(options) => textEditor(options)}
></Column>
<Column style={{ maxWidth: "15%" }} rowEditor>
edit
</Column>
</DataTable>
</div>
);
};
这可以通过对上面的代码进行一些调整来实现。
dataKey
上引入道具 DataTable
,这对于您的数据来说应该是独特,并且您可以在创建行时添加到数据中,我使用 id
进行演示。onRowEditChange
,以便表可以处理编程激活。editingRows
,您将在指示哪一行处于编辑模式的状态下传递该属性。这是表通过利用步骤 1 中提到的 dataKey
属性在内部处理的。请参阅下面的代码,将有助于进一步理解上述几点。
* 我为
users
状态使用了一些硬编码值,以便代码可以工作。不要忘记更改数据的值
export const Table = () => {
const [users, setUsers] = useState([
{ id: 'john1', firstName: "John1", lastName: "Doe1", email: "[email protected]", phone: "1234567890", freeTextField: "Random1" },
{ id: '2', firstName: "John2", lastName: "Doe2", email: "[email protected]", phone: "2345678901", freeTextField: "Random2" },
{ id: '3', firstName: "John3", lastName: "Doe3", email: "[email protected]", phone: "3456789012", freeTextField: "Random3" },
{ id: '4', firstName: "John4", lastName: "Doe4", email: "[email protected]", phone: "4567890123", freeTextField: "Random4" },
{ id: '5', firstName: "John5", lastName: "Doe5", email: "[email protected]", phone: "5678901234", freeTextField: "Random5" },
]);
const [editingRows, setEditingRows] = useState({});
const handleAddRow = (): void => {
const newRow: any = {
id: users.length + 1,
firstName: "",
lastName: "",
email: "",
phone: "",
freeTextField: "",
};
setUsers((prevList: any) => [newRow, ...prevList]);
const val = {...{ [`${users.length + 1}`]: true } }
setEditingRows(val);
};
const onRowEditComplete = (e: any) => {
const _users = [...users];
const { newData, index } = e;
_users[index] = newData;
setUsers(_users);
};
const textEditor = (options: any) => {
return (
<InputText
type="text"
value={options.value}
onChange={(e) => options.editorCallback(e.target.value)}
/>
);
};
const onRowEditChange = (e:any) => {
setEditingRows(e.data);
}
return (
<div className="table-wrapper">
<h2 className="table-name">PrimeReact data table</h2>
<button onClick={handleAddRow}>add row</button>
<DataTable
value={users}
tableStyle={{ minWidth: "50rem" }}
editMode="row"
editingRows={editingRows}
dataKey="id"
onRowEditChange={onRowEditChange}
onRowEditComplete={onRowEditComplete}
>
<Column
field="firstName"
header="firstName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="lastName"
header="lastName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="email"
header="email"
editor={(options) => textEditor(options)}
></Column>
<Column
field="phone"
header="phone"
editor={(options) => textEditor(options)}
></Column>
<Column style={{ maxWidth: "15%" }} rowEditor>
edit
</Column>
</DataTable>
</div>
);
};
正如我们的朋友@Petros 之前提到的,您需要 3 点
添加 useState 但我会将其修改为适用于任何添加的新行
任何没有定义 id 的新行都将是未定义的,所以我们将使用这个技巧
const [editingRows, setEditingRows] = useState({undefined: true});
在handleAddRow中不需要
const val = {...{ [`${users.length + 1}`]: true } }
setEditingRows(val);
handleAddRow 中的小注释,如果有人尝试复制...请确保您不会添加像 {} 这样的空对象,也许至少不会有一个像 { dummy: "" } 这样的空字段
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { data } from "../data";
import { useState } from "react";
import { InputText } from "primereact/inputtext";
export const Table = () => {
const [users, setUsers] = useState(data);
const [editingRows, setEditingRows] = useState({undefined: true});
const handleAddRow = (): void => {
const newRow: any = {
firstName: "",
lastName: "",
email: "",
phone: "",
freeTextField: "",
};
setUsers((prevList: any) => [newRow, ...prevList]);
};
const onRowEditChange = (e:any) => {
setEditingRows(e.data);
}
const onRowEditComplete = (e: any) => {
const _users = [...users];
const { newData, index } = e;
_users[index] = newData;
setUsers(_users);
};
const textEditor = (options: any) => {
return (
<InputText
type="text"
value={options.value}
onChange={(e) => options.editorCallback(e.target.value)}
/>
);
};
return (
<div className="table-wrapper">
<h2 className="table-name">PrimeReact data table</h2>
<button onClick={handleAddRow}>add row</button>
<DataTable
dataKey="id"
value={users}
tableStyle={{ minWidth: "50rem" }}
editMode="row"
editingRows={editingRows}
onRowEditComplete={onRowEditComplete}
>
<Column
field="firstName"
header="firstName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="lastName"
header="lastName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="email"
header="email"
editor={(options) => textEditor(options)}
></Column>
<Column
field="phone"
header="phone"
editor={(options) => textEditor(options)}
></Column>
<Column style={{ maxWidth: "15%" }} rowEditor>
edit
</Column>
</DataTable>
</div>
);
};