如何在本地存储和useeffect中保持状态?

问题描述 投票:0回答:1

嘿,我在反应应用程序中遇到了问题,因为我是反应初学者。我有一个简单的应用程序。这是一个时间跟踪应用程序
它有一个简单的界面。非常基本的应用程序。问题是我有从 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">
                &larr; 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;
reactjs asp.net asp.net-core asp.net-mvc-4 asp.net-web-api
1个回答
0
投票

因此,即使在刷新或页面更改后,您也希望保持按钮的状态。为此,您需要使用

localStorage

我添加了一些块来保存变量的状态,而不是状态(当您更改页面时会丢失)。

localStorage

也许你应该考虑拆分这个组件,让按钮成为独立的组件。它可以帮助您更清楚地了解一切。

© www.soinside.com 2019 - 2024. All rights reserved.