嘿,我在反应应用程序中遇到了问题,因为我是反应初学者。我有一个简单的应用程序。这是一个时间跟踪应用程序
它有一个简单的界面。非常基本的应用程序。问题是我有从 ASP.NET Core 后端 API 获取的所有员工的列表。当我点击员工时,问题是屏幕上有签到和签出按钮,我可以在其中签到和签出我的时间。时间显示在最后。但我想持续存在的问题是,例如,我的处理条件是,当我第一次签入时,按钮将签出按钮将使他可以进行签出。当我按结帐键时。记下结账时间,并禁用结账按钮并启用签入。当我签入并转到结帐时,我刷新或返回按钮时,它不会持续我的状态,我希望实现这一点。请提供解决方案,如何按照我的尝试使用本地存储保留我的按钮状态。但本地存储不起作用。它无法存储我的状态。我想保持我的状态,就像当我签入或签出或返回按钮时,然后它会向我显示或选择最近的按钮。请为我提供本地存储的解决方案。并将工作放入employeetimetracking.js
import React, { useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import { fetchEmployeeById,checkIn,checkOut,fetchEmployeeStatus} from '../api/Employeeapi'; // Import your fetchEmployeeById method
function EmployeeTimeTracking() {
const { employeeId } = useParams(); // Get the employee ID from the URL
const [employeeName, setEmployeeName] = useState("Employee"); // Default name
const [status, setStatus] = useState('checkOut');
const [checkInTime, setCheckInTime] = useState(null);
const [checkOutTime, setCheckOutTime] = useState(null);
const [timeTrackingId, setTimeTrackingId] = useState(null); // To store the check-in ID
// set the message for to display success and error msg
//const[message,setmessage]=useState("");
useEffect(() => {
// Fetch employee data by ID
const fetchEmployee = async () => {
try {
const employee = await fetchEmployeeById(employeeId); // Call your fetchEmployeeById method
setEmployeeName(employee.name); // Assuming `name` is the field in the response
} catch (error) {
console.error("Error fetching employee:", error);
}
};
const fetchStatus = async () => {
try {
const data = await fetchEmployeeStatus(employeeId); // Call the fetchEmployeeStatus function
setStatus(data.status);
setCheckInTime(data.checkInTime ? new Date(data.checkInTime).toLocaleTimeString("en-US", { timeZone: "America/New_York" }) : null);
setCheckOutTime(data.checkOutTime ? new Date(data.checkOutTime).toLocaleTimeString("en-US", { timeZone: "America/New_York" }) : null);
} catch (error) {
console.error("Error fetching employee status:", error);
}
};
fetchStatus();
fetchEmployee();
}, [employeeId]);
// Check-in function
const handleCheckIn = async () => {
try {
const data = await checkIn(employeeId);
setTimeTrackingId(data.id); // Store the ID of the check-in record
setCheckInTime(new Date().toLocaleTimeString("en-US", { timeZone: "America/New_York" }));
setStatus('checkedIn');
} catch (error) {
console.error("Check-in failed:", error);
}
};
const handleCheckOut = async () => {
try {
await checkOut(timeTrackingId);
setCheckOutTime(new Date().toLocaleTimeString("en-US", { timeZone: "America/New_York" }));
setStatus('checkedOut');
} catch (error) {
console.error("Check-out failed:", error);
}
};
return (
<div className="p-3 max-w-md mx-auto">
{/* Back Button */}
<Link to="/" className="text-blue-500 absolute left-2 top-0 hover:underline">
← Back to Employee List
</Link>
<div className="p-4 max-w-md mx-auto">
<h2 className="text-2xl font-bold mb-4 text-center">
Time Tracking for {employeeName} {/* Display employee name */}
</h2>
<div className="flex flex-col space-y-4 items-center">
<button
onClick={handleCheckIn}
disabled={status === 'checkedIn'}
className={`px-4 py-2 w-full sm:w-1/2 rounded ${status === 'checkedIn' ? 'bg-gray-300 cursor-not-allowed' : 'bg-green-500 hover:bg-green-600'} text-white font-semibold transition`}
>
Check In
</button>
<button
onClick={handleCheckOut}
disabled={status !== 'checkedIn'}
className={`px-4 py-2 w-full sm:w-1/2 rounded ${status !== 'checkedIn' ? 'bg-gray-300 cursor-not-allowed' : 'bg-red-500 hover:bg-red-600'} text-white font-semibold transition`}
>
Check Out
</button>
</div>
{/* {message && (
<div className="text-center mb-4 p-2 rounded bg-green-100 text-green-700">
{message}
</div>
)} */}
<div className="mt-6 text-center">
<p className="text-lg">Check-In Time: {checkInTime || 'Not Checked In'}</p>
<p className="text-lg">Check-Out Time: {checkOutTime || 'Not Checked Out'}</p>
</div>
</div>
</div>
);
}
export default EmployeeTimeTracking;
员工时间跟踪.js
Employeeapi.js
import axios from 'axios';
const API_URL = 'http://localhost:5049/api/timetraking';
// export const fetchEmployeeTimeTracking = async (employeeId) => {
// const response = await axios.get(`${API_URL}/timetrackingid/${employeeId}`);
// return response.data;
// };
// Fetch all employees
export const fetchEmployees = async () => {
try {
const response = await axios.get(`${API_URL}/employees`); // Make sure this matches your backend
return response.data; // Return the data directly
} catch (error) {
console.error("Error fetching employees:", error);
console.log(`API URL for employees: ${API_URL}/employees`);
throw error; // Rethrow the error so it can be caught in the component
}
};
export const fetchEmployeeById = async (id) => {
try {
const response = await axios.get(`${API_URL}/employees/${id}`); // Adjust the URL as needed
// console.log("Employee ID from URL:", id); // Log the ID
return response.data;
} catch (error) {
console.error(`Error fetching employee with ID ${id}:`, error);
throw error; // Rethrow the error for handling in the component
}
};
export const checkIn = async (employeeId) => {
try {
const response = await axios.post(`${API_URL}/checkin`, {
employeeId: employeeId, // Pass any other required data here
});
return response.data;
} catch (error) {
console.error("Error during check-in:", error);
throw error;
}
};
// Check-out an employee
export const checkOut = async (timeTrackingId) => {
try {
const response = await axios.post(`${API_URL}/checkout/${timeTrackingId}`);
return response.data;
} catch (error) {
console.error("Error during check-out:", error);
throw error;
}
};
// Fetch employee status by employee ID
export const fetchEmployeeStatus = async (employeeId) => {
try {
const response = await axios.get(`${API_URL}/status/${employeeId}`); // Adjusting to match your endpoint
return response.data; // Return the data directly
} catch (error) {
console.error(`Error fetching status for employee ${employeeId}:`, error);
throw error; // Rethrow the error for handling in the component
}
};
Employeelist.js
import React, {useEffect, useState} from 'react';
import { Link } from 'react-router-dom';
import { fetchEmployees } from '../api/Employeeapi';
// const employees = [
// { id: 1, name: 'Alice' },
// { id: 2, name: 'Bob' },
// { id: 3, name: 'Charlie' },
// { id: 4, name: 'Leon' },
// ];
function EmployeeList() {
const [employees, setEmployees] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const loadEmployees = async () => {
try {
const data = await fetchEmployees();
setEmployees(data);
} catch (err) {
setError("Failed to load employees.");
}
};
loadEmployees();
}, []);
if (error) {
return <div>Error: {error}</div>;
}
return (
<div className="p-4 max-w-2xl mx-auto">
<h1 className="text-2xl font-bold mb-4 text-center">Employee List</h1>
<div className="grid gap-4 grid-cols-1 sm:grid-cols-2">
{employees.map(emp => (
<Link
key={emp.id}
to={`/employee/${emp.id}`}
className="p-4 bg-blue-100 rounded shadow hover:bg-blue-200 transition"
>
<p className="text-lg font-semibold">{emp.name}</p>
</Link>
))}
</div>
</div>
);
}
export default EmployeeList;
因此,即使在刷新或页面更改后,您也希望保持按钮的状态。为此,您需要使用
localStorage
。
我添加了一些块来保存变量的状态,而不是状态(当您更改页面时会丢失)。
localStorage
也许你应该考虑拆分这个组件,让按钮成为独立的组件。它可以帮助您更清楚地了解一切。