我正在使用 React-TypeScript 創建員工串列,編輯和洗掉他們。但是,我的編輯按鈕在單擊時不執行任何操作。關于如何解決這個問題的任何想法?
我對“洗掉”功能使用了相同的代碼并且運行良好。以下是我撰寫的兩個 react-typescript 檔案,我還有一個 app.tsx 檔案,所有這些檔案都被匯入其中。
CreateEmployee.tsx
import React, { useState, FC, ChangeEvent } from "react";
import { Link } from "react-router-dom";
import { IEmployee } from "../../Interfaces";
import EmployeeList from "./EmployeeList";
export const CreateEmployee: FC = () => {
const [employeeName, setEmployeeName] = useState<string>("");
const [employeeId, setEmployeeId] = useState<any>("");
const [employeeList, setEmployeeList] = useState<IEmployee[]>([]);
// get the data from the input and add it to the state
const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
if (event.target.name === "employeename") {
setEmployeeName(event.target.value);
} else {
setEmployeeId(event.target.value);
}
};
// add id and name to the employee list
const addEmployee = (): void => {
const newEmployee = {
employeeId: employeeId,
employeeName: employeeName,
};
setEmployeeList([...employeeList, newEmployee]);
setEmployeeName("");
setEmployeeId("");
};
// delete employee from the list
const deleteEmployee = (employeeNameToDelete: string): void => {
setEmployeeList(
employeeList.filter(
(employee) => employee.employeeName !== employeeNameToDelete
)
);
};
// edit employee name and id in the list
const editEmployee = (
employeeNameToEdit: string,
employeeIdToEdit: string
): void => {
setEmployeeList(
employeeList.map((employee) => {
if (employee.employeeName === employeeNameToEdit) {
employee.employeeId = employeeIdToEdit;
}
return employee;
})
);
};
return (
<div>
<h1>Create Employee</h1>
<div>
<label>Employee Id:</label>
<input
type="text"
name="employeeid"
value={employeeId}
onChange={(e) => setEmployeeId(e.target.value)}
/>
<label>Employee Name:</label>
<input
type="text"
name="employeename"
value={employeeName}
onChange={(e) => setEmployeeName(e.target.value)}
/>
<button type="submit" onClick={addEmployee}>
Submit
</button>
</div>
<div>
<Link to="/employeelist">Employee List</Link>
<Link to="/engagementList">Engagement List</Link>
</div>
<div className="employee-list">
<h1>Employee List</h1>
{employeeList.map((employee: IEmployee, key: number) => {
return (
<EmployeeList
key={key}
employee={employee}
deleteEmployee={deleteEmployee}
editEmployee={editEmployee}
/>
);
})}
</div>
</div>
);
};
員工串列.tsx
import React from "react";
import { IEmployee } from "../../Interfaces";
import { CreateEmployee } from "../employeeComponents/CreateEmployee";
interface Props {
employee: IEmployee;
deleteEmployee: (employeeNameToDelete: string) => void;
editEmployee: (employeeNameToEdit: string, employeeIdToEdit: string) => void;
}
export const EmployeeList = ({ employee, deleteEmployee, editEmployee }: Props) => {
return (
<div>
<div className="employee-list">
<div className="content">
<span>{employee.employeeId}</span>
<span>{employee.employeeName}</span>
</div>
<button
onClick={() => {
deleteEmployee(employee.employeeName);
}}
>
Delete
</button>
<button
onClick={() => {
editEmployee(employee.employeeName, employee.employeeId);
}}
>
Edit
</button>
</div>
</div>
);
};
export default EmployeeList;
uj5u.com熱心網友回復:
您正在employeeList其 setter中使用當前狀態的值。而是傳遞一個物件的useState,你可以傳遞,而不是一個函式,老態作為引數。例如:
setEmployeeList((oldEmployeeList) =>
(oldEmployeeList.map((employee) => {
if (employee.employeeName === employeeNameToEdit) {
employee.employeeId = employeeIdToEdit;
}
return employee;
}))
);
uj5u.com熱心網友回復:
這是狀態突變的問題,您正在修改正在編輯的員工物件,而不是回傳新的員工物件參考。由于特定的employee物件參考不會改變 React 可能會放棄重新渲染它們,因為它在 Reconciliation 期間使用淺參考相等性檢查。
const editEmployee = (
employeeNameToEdit: string,
employeeIdToEdit: string
): void => {
setEmployeeList(employeeList => employeeList.map((employee) => {
if (employee.employeeName === employeeNameToEdit) {
return { // <-- return new object reference
...employee, // <-- shallow copy previous state
employeeId: employeeIdToEdit, // <-- set property value
}
}
return employee; // <-- else return previous state
}));
};
uj5u.com熱心網友回復:
問題不在于你改變了狀態,你的editEmployee函式使用setEmployeeList正確——map回傳一個新陣列,而 React 正在檢測這個變化并重新渲染組件。您可以通過插入console.log('rendering');到您的CreateEmployee函式中來驗證這一點。
問題是這editEmployee只是創建舊employeeList.
您可能希望它做的是用編輯過的員工 ID 和姓名填充文本欄位,然后在單擊提交按鈕時更新您的員工串列。
const editEmployee = (
employeeNameToEdit: string,
employeeIdToEdit: string
): void => {
// This will put these two items into the text fields for editing
setEmployeeId(employeeIdToEdit);
setEmployeeName(employeeNameToEdit);
};
并更改addEmployee為這樣的內容(您可以將其重命名為addOrUpdateEmployee):
const addEmployee = (): void => {
const newEmployee = {
employeeId: employeeId,
employeeName: employeeName,
};
// Consider it's a new employee if the employee with this employeeId
// does not exist in the list of employees.
// Otherwise, it's an edited employee
let employeeIndex;
if (
employeeList.some((employee, index) => {
employeeIndex = index;
return employee.employeeId === employeeId;
})
) {
// This is not state mutation ...
employeeList[employeeIndex] = newEmployee;
// ...because we set it to a copy of the mutated array
setEmployeeList([...employeeList]);
} else {
setEmployeeList([...employeeList, newEmployee]);
}
setEmployeeName('');
setEmployeeId('');
};
決定是新員工還是編輯員工的邏輯完全是我的,您應該使用適合您的應用程式的任何內容。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/371416.html
