React点击表格行取数、useEffect无限请求及reduce报错问题求助
React拉取API数据相关问题修复方案
问题1:点击表格行无法正确复制该行name属性
错误原因
- 函数组件不存在
this指向,this.d.name写法无效 e.target指向触发点击的实际DOM节点,可能是行内的<td>而非<tr>,读取e.target.value或子节点内容的方式不稳定
修复方案
直接使用map遍历上下文中的当前行数据对象d,直接获取d.name即可,不需要读取DOM内容:
onClick={() => { navigator.clipboard.writeText(`exiva "${d.name}"`); }}
问题2:useEffect无限触发接口请求
错误原因
- 你将
members加入了useEffect的依赖项,而useEffect内部调用了setMembers修改members值,会触发useEffect重复执行,形成死循环 - state更新是异步操作,调用
setMembers后立即读取members拿到的还是更新前的旧值
修复方案
将members从useEffect依赖项中移除,如果不需要在其他地方使用全量成员数据,甚至可以不用将members存入state,直接使用接口返回的临时变量处理即可。
问题3:reduce调用报错/无法遍历全部成员角色
错误原因
resp.guild是对象类型,而非数组,reduce是数组原型方法,直接对resp.guild调用reduce会报错- 你要遍历的是
resp.guild.members这个数组,而非resp.guild本身 - 调用
setMembers后立即读取members拿到的是旧值,此时对旧值调用reduce也会出现异常
修复方案
直接对接口返回的resp.guild.members数组调用reduce方法,合并所有角色数据:
const allCharacters = resp.guild.members.reduce((accum, iter) => { accum.push(...iter.characters); return accum; }, []);
最终可运行完整代码
import React, { useState, useEffect } from "react"; const Tabledata = ({ guildName }) => { const [membersOnline, setMembersOnline] = useState([]); const [header, setHeader] = useState(""); useEffect(() => { // 避免guildName为空时发起无效请求 if (!guildName) return; fetch(`https://api.tibiadata.com/v2/guild/${guildName}.json`) .then((res) => res.json()) .then((resp) => { setHeader(resp.guild.data.name); // 直接遍历resp.guild.members数组合并所有角色 const allCharacters = resp.guild.members.reduce((accum, iter) => { accum.push(...iter.characters); return accum; }, []); // 过滤在线成员 setMembersOnline(allCharacters.filter(player => player.status !== "offline")); }) .catch((err) => console.log(err)); }, [guildName]); // 仅保留guildName作为依赖项 return ( <div className="container"> <h1>{header || "Enemies Online"}</h1> <table className="table table-bordered"> <thead> <tr> <th>Name</th> <th>Level</th> <th>Vocation</th> <th>Status</th> </tr> </thead> <tbody> {membersOnline.map((d) => ( <tr key={d.id} // 直接使用当前遍历的d对象获取name onClick={() => { navigator.clipboard.writeText(`exiva "${d.name}"`); }} > <td>{d.name}</td> <td>{d.level}</td> <td>{d.vocation}</td> <td>{d.status}</td> </tr> ))} </tbody> </table> </div> ); }; export default Tabledata;
内容的提问来源于stack exchange,提问作者rafaelcarrilho
相关产品推荐
相关产品推荐

