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

React迭代条件渲染时按钮ID取值滞后1位问题修复

问题说明

预约场景下按钮ID匹配异常:点击类名为greenButton的可预约按钮触发预约逻辑后,对应位置的已预约按钮(类名yellowButton)无法匹配正确ID,yellowButton绑定的ID始终比同位置greenButton的ID小1:当greenButton绑定的buttonId取值为x时,同位置yellowButton的状态判断逻辑使用ID为x,但按钮实际绑定的buttonId为x-1。

根因分析

ID取值错位由后置自增运算符的执行逻辑导致:

  • 原代码中let buttonId = id++为后置自增写法,执行顺序为:先将id当前的原值赋值给buttonId,再将id变量自身加1
  • 后续判断预约状态、占用状态的逻辑myBookings().result.includes(id)、occupiedSlots().result.includes(id),调用的是自增完成后的id值,和按钮实际绑定的buttonId差值为1,最终导致状态判断和按钮ID完全错位。
    原代码中的日志输出可直接印证该问题:渲染yellowButton时打印的buttonId为1,此时id已经完成自增变为2,状态判断逻辑使用id=2做匹配,相当于把ID为2的预约状态,错误绑定到了ID为1的按钮上。
修复方案

调整ID自增时机,所有状态判断、按钮属性绑定统一使用同一个buttonId值,待当前按钮的所有渲染逻辑执行完成后,再对id做自增操作,避免取值错位。
优化后的代码如下:

const renderTableData = () => {
  let id = 1;
  return (
    <tr>
      {days.map((val) => (
        <td>
          {timeSlot.map((time, i) => {
            // 固定当前按钮的ID,所有逻辑统一使用该值
            const buttonId = id;
            let buttonEl;
            // 状态判断和按钮绑定都用同一个buttonId,不存在差值
            if (myBookings().result.includes(buttonId)) {
              buttonEl = (
                <button
                  id={buttonId}
                  className="yellowButton"
                  onClick={() => cancelBooking(buttonId)}
                >
                  {time}
                </button>
              );
            } else if (occupiedSlots().result.includes(buttonId)) {
              buttonEl = (
                <button id={buttonId} className="redButton">
                  {time}
                </button>
              );
            } else {
              buttonEl = (
                <button
                  id={buttonId}
                  className="greenButton"
                  onClick={() => {
                    BookSlot({ id: buttonId });
                  }}
                >
                  {time}
                  {buttonId}
                </button>
              );
            }
            // 当前按钮逻辑全部跑完后再自增ID
            id++;
            return buttonEl;
          })}
        </td>
      ))}
    </tr>
  );
};

补充说明:cancelBooking、BookSlot等事件回调直接传入当前作用域固定的buttonId即可,不要依赖外层可变的id变量,可彻底避免闭包取值错位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:03:21