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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:15:00