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
相关产品推荐
相关产品推荐

