You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中动态修改出勤状态颜色异常问题排查

问题:React中出勤状态颜色判断失效,全部显示绿色

开发React项目时,需要为从数据库获取的present(出勤)和absent(缺勤)数据设置不同背景色。使用条件判断后,所有状态都显示为绿色,尝试多种方案均无效,寻求问题原因及解决方法。

代码如下:

import React, { useEffect, useState } from 'react'
import { NavLink, useParams } from 'react-router-dom'
import Navbar from './Navbar';
import { useNavigate } from 'react-router-dom';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

const Contractor = () => {
    const [contractor, setContractor] = useState([])
    const { PM_id } = useParams();

    // 原错误的全局样式定义已移除
    // const color = contractor[0]?.attstatus === "present" ? 'green' : 'red';
    // const styles = {  backgroundColor: color };

    const getMemberId = async (PM_id) => {
        try {
            const res = await fetch(`/getattendance/${PM_id}`, {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json"
                },
                credentials: "include"
            })
            const result = await res.json()
            setContractor(result)
        } catch (error) {
            console.log(error);
        }
    }

    // 调用数据接口加载数据
    useEffect(() => {
        if (PM_id) {
            getMemberId(PM_id);
        }
    }, [PM_id])

    return (
        <>
            <ToastContainer />
            <table>
                {
                    contractor?.map((item, i) => {
                        return (
                            <tbody key={i}>
                                <tr>
                                    <th scope="row">{item.attdate}</th>
                                    <td>
                                        {/* 针对当前item实时计算样式 */}
                                        <span 
                                            style={{ backgroundColor: item.attstatus === "present" ? 'green' : 'red' }} 
                                            className="badge rounded-pill"
                                        >
                                            {item.attstatus} 
                                        </span> 
                                        <i onClick={() => modalClick(item.atte_id)} data-bs-toggle="modal" data-bs-target="#exampleModal" className="bi bi-pencil-square"></i> 
                                    </td>
                                </tr>
                            </tbody>
                        )
                    })
                }
            </table>
        </>
    )
}

export default Contractor

当前输出效果:

所有出勤状态均显示为绿色


问题原因:

  • 你将样式styles定义在组件顶层,仅根据数组第一个元素contractor[0]的attstatus计算一次,所有列表项都会复用这个固定样式,完全忽略了每个item自身的状态。
  • 若数组第一个元素的attstatus是present,所有项都会显示绿色;即便后续元素状态不同,也不会重新计算样式。

解决方法:

  1. 移除全局样式定义:删掉组件顶层的color和styles变量,避免固定样式复用。
  2. 遍历项内实时计算样式:在map遍历每个item时,直接根据当前item的attstatus动态生成样式,确保每个项的颜色匹配自身状态。
  3. 补充必要组件逻辑:
    • 添加useEffect调用数据接口,确保数据能正常加载。
    • 给列表项补充key属性,符合React列表渲染规范。
    • 修复原代码中class应为className的React语法问题。

内容的提问来源于stack exchange,提问作者user20658000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:02:43