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

React复选框无法勾选且onChange事件未触发处理函数

React复选框onChange事件未触发的问题修复

问题根源及修复方案:

  • useEffect无限循环:原代码中useEffect依赖items,每次setItems都会触发重新请求,导致组件频繁重渲染,干扰事件正常触发。将依赖数组改为[],仅在组件挂载时加载一次数据。
  • 勾选状态存储错误:用数组存储勾选状态时,item._id(字符串类型)无法作为有效索引,导致状态更新异常。改用对象存储,以item._id为键记录每个条目的勾选状态。
  • 多余的默认行为阻止:复选框onChange事件中调用e.preventDefault()会破坏默认勾选逻辑,直接删除该语句。
  • 列表key位置错误:React列表渲染的key应加在循环的最外层元素(<tr>)上,而非内部<td>,确保列表项正确识别。

修复后的完整代码:

import React, { useState, useEffect } from "react";
import axios from "axios";

function Table() {
    const [items, setItems] = useState([]);
    // 改用对象存储勾选状态,初始为空对象
    const [isChecked, setIsChecked] = useState({});

    useEffect(() => {
        const loadData = async () => {
            try {
                const res = await axios.get('http://localhost:9000/');
                setItems(res.data);
            } catch (err) {
                console.log(err);
            }
        };
        loadData();
    }, []); // 空数组依赖,仅挂载时执行一次

    const handleOnChange = (itemId) => {
        console.log("Change event triggered");
        setIsChecked(prevState => ({
            ...prevState,
            [itemId]: !prevState[itemId]
        }));
    };

    const ItemList = ({ items }) => {
        const listItems = items.map((item) => (
            // 给tr添加唯一key
            <tr key={item._id} className="border border-slate-300">
                <td>
                    <input 
                        type="checkbox" 
                        name="checkbox" 
                        checked={isChecked[item._id] || false} 
                        onChange={() => handleOnChange(item._id)} 
                    />
                </td>
                <td>{item.name}</td>
                <td>{item.quantity}</td>
                <td>{item.price}</td>
            </tr>
        ));
        return <>{listItems}</>;
    };

    return (
        <div className="grid grid-flow-col auto-rows-max max-w-full justify-center place-content-center">
            <table className="table-auto">
                <thead>
                    <tr>
                        <th className="border border-slate-300 ...">Checked</th>
                        <th className="border border-slate-300 ...">Items</th>
                        <th className="border border-slate-300 ...">Quantity</th>
                        <th className="border border-slate-300 ...">Price</th>
                    </tr>
                </thead>
                <tbody>
                    <ItemList items={items} />
                </tbody>
            </table>
        </div>
    );
}

export default Table;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:28:09