如何使用 ReactJS 创建带有添加删除和搜索过滤器的可编辑表?
表格用于显示一组数据。在某些项目中,您需要使用可编辑/不可编辑模式实现动态表,用户可以在其中添加或删除任何行。此外,React 的 Material UI 有一个可定制的 Table Component 可用,并且非常容易集成,但是没有这样的功能来单独处理行的添加和删除。我们将使用 React.js 和 Material UI 并在其中实现这些功能。
创建 React 应用程序并安装模块:
第 1 步:使用以下命令创建一个 React 应用程序。
npx create-react-app foldername
第 2 步:创建项目文件夹(即文件夹名称)后,使用以下命令移动到该文件夹。
cd foldername
- 第 3 步:创建 React.js 应用程序后,使用以下命令安装material-ui模块。
npm install @material-ui/core npm install @material-ui/icons npm install @material-ui/lab
默认项目结构:它将如下所示。
更改项目结构:我们不需要 App.css、logo.svg 等文件。删除它们并添加一个新文件 TableDemo.js,我们的表格组件将驻留在其中。
示例:现在在 App.js 和 TableDemo.js 文件中相应地写下以下代码。在这里,App 是我们的默认组件,我们已经替换了默认代码。
App.js
import React from "react";
import TableDemo from "./TableDemo";
function App() {
return (
{/* Header with inline css */}
Geeks For Geeks Material UI Table
{/* Table component below header */}
)
}
export default App;
TableDemo.js
import React, { useState } from "react";
import CreateIcon from "@material-ui/icons/Create";
import {
Box, Button, Snackbar, Table,
TableBody, TableCell, TableHead, TableRow
} from "@material-ui/core";
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
import AddBoxIcon from "@material-ui/icons/AddBox";
import DoneIcon from "@material-ui/icons/Done";
import ClearIcon from "@material-ui/icons/Clear";
import { makeStyles } from "@material-ui/core/styles";
import Alert from "@material-ui/lab/Alert";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
// Creating styles
const useStyles = makeStyles({
root: {
"& > *": {
borderBottom: "unset",
},
},
table: {
minWidth: 650,
},
snackbar: {
bottom: "104px",
},
});
function TableDemo() {
// Creating style object
const classes = useStyles();
// Defining a state named rows
// which we can update by calling on setRows function
const [rows, setRows] = useState([
{ id: 1, firstname: "", lastname: "", city: "" },
]);
// Initial states
const [open, setOpen] = React.useState(false);
const [isEdit, setEdit] = React.useState(false);
const [disable, setDisable] = React.useState(true);
const [showConfirm, setShowConfirm] = React.useState(false);
// Function For closing the alert snackbar
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
setOpen(false);
};
// Function For adding new row object
const handleAdd = () => {
setRows([
...rows,
{
id: rows.length + 1, firstname: "",
lastname: "", city: ""
},
]);
setEdit(true);
};
// Function to handle edit
const handleEdit = (i) => {
// If edit mode is true setEdit will
// set it to false and vice versa
setEdit(!isEdit);
};
// Function to handle save
const handleSave = () => {
setEdit(!isEdit);
setRows(rows);
console.log("saved : ", rows);
setDisable(true);
setOpen(true);
};
// The handleInputChange handler can be set up to handle
// many different inputs in the form, listen for changes
// to input elements and record their values in state
const handleInputChange = (e, index) => {
setDisable(false);
const { name, value } = e.target;
const list = [...rows];
list[index][name] = value;
setRows(list);
};
// Showing delete confirmation to users
const handleConfirm = () => {
setShowConfirm(true);
};
// Handle the case of delete confirmation where
// user click yes delete a specific row of id:i
const handleRemoveClick = (i) => {
const list = [...rows];
list.splice(i, 1);
setRows(list);
setShowConfirm(false);
};
// Handle the case of delete confirmation
// where user click no
const handleNo = () => {
setShowConfirm(false);
};
return (
Record saved successfully!
{isEdit ? (
{rows.length !== 0 && (
{disable ? (
) : (
)}
)}
) : (
)}
First Name
Last Name
City
{rows.map((row, i) => {
return (
{isEdit ? (
handleInputChange(e, i)}
/>
handleInputChange(e, i)}
/>
) : (
{row.firstname}
{row.lastname}
{row.city}
)}
{isEdit ? (
) : (
)}
{showConfirm && (
)}
);
})}
);
}
export default TableDemo;
TableDemo.js
import React, { useState } from "react";
import CreateIcon from "@material-ui/icons/Create";
import {
Box, Button, Snackbar, Table,
TableBody, TableCell, TableHead, TableRow
} from "@material-ui/core";
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
import AddBoxIcon from "@material-ui/icons/AddBox";
import DoneIcon from "@material-ui/icons/Done";
import ClearIcon from "@material-ui/icons/Clear";
import { makeStyles } from "@material-ui/core/styles";
import Alert from "@material-ui/lab/Alert";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
// Creating styles
const useStyles = makeStyles({
root: {
"& > *": {
borderBottom: "unset",
},
},
table: {
minWidth: 650,
},
snackbar: {
bottom: "104px",
},
});
function TableDemo() {
// Creating style object
const classes = useStyles();
// Defining a state named rows
// which we can update by calling on setRows function
const [rows, setRows] = useState([
{ id: 1, firstname: "", lastname: "", city: "" },
]);
// Initial states
const [open, setOpen] = React.useState(false);
const [isEdit, setEdit] = React.useState(false);
const [disable, setDisable] = React.useState(true);
const [showConfirm, setShowConfirm] = React.useState(false);
// Function For closing the alert snackbar
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
setOpen(false);
};
// Function For adding new row object
const handleAdd = () => {
setRows([
...rows,
{
id: rows.length + 1, firstname: "",
lastname: "", city: ""
},
]);
setEdit(true);
};
// Function to handle edit
const handleEdit = (i) => {
// If edit mode is true setEdit will
// set it to false and vice versa
setEdit(!isEdit);
};
// Function to handle save
const handleSave = () => {
setEdit(!isEdit);
setRows(rows);
console.log("saved : ", rows);
setDisable(true);
setOpen(true);
};
// The handleInputChange handler can be set up to handle
// many different inputs in the form, listen for changes
// to input elements and record their values in state
const handleInputChange = (e, index) => {
setDisable(false);
const { name, value } = e.target;
const list = [...rows];
list[index][name] = value;
setRows(list);
};
// Showing delete confirmation to users
const handleConfirm = () => {
setShowConfirm(true);
};
// Handle the case of delete confirmation where
// user click yes delete a specific row of id:i
const handleRemoveClick = (i) => {
const list = [...rows];
list.splice(i, 1);
setRows(list);
setShowConfirm(false);
};
// Handle the case of delete confirmation
// where user click no
const handleNo = () => {
setShowConfirm(false);
};
return (
Record saved successfully!
{isEdit ? (
{rows.length !== 0 && (
{disable ? (
) : (
)}
)}
) : (
)}
First Name
Last Name
City
{rows.map((row, i) => {
return (
{isEdit ? (
handleInputChange(e, i)}
/>
handleInputChange(e, i)}
/>
) : (
{row.firstname}
{row.lastname}
{row.city}
)}
{isEdit ? (
) : (
)}
{showConfirm && (
)}
);
})}
);
}
export default TableDemo;
运行应用程序的步骤:使用以下命令从项目的根目录运行应用程序。
npm start
输出:现在打开浏览器并转到http://localhost:3000/ ,您将看到以下输出。
解释:
- useState() 是 ReactJs 中的一个钩子,它允许功能组件具有状态。我们在这个函数中传递初始状态,它返回一个变量和一个更新该状态的函数。使用它,我们可以处理编辑/非编辑模式和相应显示的按钮。
- 最初,表格将以非编辑模式显示。单击 EDIT 后,表格行将在编辑模式下修改,用户可以添加尽可能多的行或删除任何行。
- 在编辑模式下,当用户尝试更改行数据时,EDIT 按钮将更改为 SAVE。点击保存后,会弹出保存提示信息。
- 当用户尝试删除一行时,将显示确认删除。如果用户选择yes ,则将删除该特定行,如果用户选择no ,则不会删除该行。
- 观察上面的输出并注意变化。您还可以根据自己的选择修改这些更改。