如何使用ReactJS将编辑函数添加到表中



我几天来一直在努力让它发挥作用,但没有成功。我使用React创建了一个表,我添加了向表中添加新人、删除他们的功能。我想增加编辑桌上人员的功能。

const [contacts, setContacts] = useContext(Context);
const [addFormData, setAddFormData] = useState({
firstName: "",
lastName: "",
salary: "",
});


const handleAddFormChange = (event) => {
event.preventDefault();
const fieldName = event.target.name;
const fieldValue = event.target.value;
const newFormData = { ...addFormData };
newFormData[fieldName] = fieldValue;
setAddFormData(newFormData);
};
const handleAddFormSubmit = (event) => {
const newContact = {
id: nanoid(),
firstName: addFormData.firstName,
lastName: addFormData.lastName,
salary: addFormData.salary,
};
const newContacts = [...contacts, newContact];
setContacts(newContacts);
setAddFormData(null); // 👈️ input required to resubmit
setShow(false); // 👈️ closes modal after submit
};

我正在使用地图功能来显示内容

{contacts.map((row,index) => (
<TableRow
key={index}
id={index}}

承认你想直接编辑你的联系人状态,你很可能需要这样的东西:

const handleContactsUpdate = (updatedContact) => setContacts((oldstate) => oldstate.filter((c) => c.id !== updatedContact.id).concat([updatedContact]))

每当用更新的联系人作为参数编辑TableRow时,它应该由TableRow调用。

一些解释:

  • setState可以传递一个函数,将当前状态(在应用setState之前(作为参数
  • 总的来说,在编辑数组时,通常更容易过滤掉正在更新的对象,然后连接更新的对象。而不是实际更新数组

所以你基本上要求setContacts将联系人设置为实际联系人,减去与updatedContact ID相同的联系人,然后在其顶部插入updatedContact.

缺点:它打乱了数组的顺序,但如果你只使用数组结构进行操作,那么在渲染一致性时,它应该不会成为问题,因为你可以(也可能应该(在.map((之前先.sort((。

更多的编辑:您还需要TableRow中的另一个函数,在编辑其中一个字段时,从所有字段中重新创建联系人对象,并将该对象传递给上方的函数

这里有一个解决方案,允许您就地编辑,而不是使用模态中的表单。只需将鼠标悬停在要编辑的单元格上,然后单击它。

const { Fragment, useEffect, useRef, useState } = React;
// Pass in some sample data
function Example({ data }) {
// Use a reference to indicate which cell is
// being edited
const editing = useRef(null);
// Set up states for the data, and the cell being edited
const [ rows, setRows ] = useState(data);
const [ edit, setEdit ] = useState({ row: null, cell: null });
// When a cell is clicked get its row and cell
// information from the dataset, and update the
// edit state
function handleEdit(e) {
const { row, cell } = e.target.dataset;
setEdit({ row: +row, cell: +cell });
}
// Called when the edit state is changed - to
// focus in input on the clicked cell
function updateFocus() {
if (editing.current) editing.current.focus();
}
// When the edit state is changed, focus the
// cursor in the input of the clicked cell
useEffect(() => updateFocus, [edit]);
// When a cell is updated, copy the state, update
// the copied state, and set the new state with the copy.
// Update the edit state
function handleUpdate(e) {
if (e.code === 'Enter') {
const { dataset: { row, cell }, name, value } = e.target;
const copy = rows.map(obj => ({ ...obj }));
copy[row][name] = value;
setRows(copy);
setEdit({ row: null, cell: null });
}
}
// Build cells from the row data returning either
// a cell with an input (depends on whether the edit
// state matches the row/cell information), or just a
// regular cell
function buildCells(row, rowId) {
return Object.entries(row).map(([key, value], cellId) => {
if (rowId === edit.row && cellId === edit.cell) {
return (
<td>
<input
ref={editing}
name={key}
data-row={rowId}
placeholder={rows[rowId][key]}
onKeyDown={handleUpdate}
/>
</td>
);
}
return (
<td
className="normal"
data-row={rowId}
data-cell={cellId}
onClick={handleEdit}
>{value}
</td>
);
});
}
// Build some rows
function buildRows(rows) {
return rows.map((row, rowId) => {
return (
<tr>
{buildCells(row, rowId)}
<td
data-row={rowId}
onClick={handleDelete}
className="delete"
>X
</td>
</tr>
);
});
}

// Remove a row when the delete button
// is clicked
function handleDelete(rowId) {
const copy = rows.map(obj => ({ ...obj }));
copy.splice(rowId, 1);
setRows(copy);
}

// Return the JSX by building some rows
return (
<table>
<tbody>
{buildRows(rows)}
</tbody>
</table>
);
}
const data = [{ id: 1, name: 'Bob', age: 12 }, { id: 2, name: 'Sam', age: 43 }];
ReactDOM.render(
<Example data={data} />,
document.getElementById('react')
);
table { border-collapse: collapse; font-size: 1.4em;}
td { padding: 0.2em 0.4em; width: 100px; border: 1px solid lightgray; }
td input { box-sizing: border-box; width: 100%; display: inline-block; border: none;  margin: 0; padding: 0; height: 100%; font-size: 1em; }
td:hover { cursor: pointer; }
td.normal:hover { background-color: #fffff0;}
td.delete { color: red; }
td.delete:hover { background-color: #ffeeee; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

最新更新