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

React函数组件嵌套循环中Offcanvas内count值异常问题

React函数组件嵌套循环中Offcanvas内count值异常的问题解决

问题原因

这是JavaScript闭包陷阱导致的。外层循环中,Offcanvas相关逻辑引用了循环变量count,但函数作用域的特性使得当Offcanvas最终渲染/触发时,循环已执行完毕,count的值固定为循环的最后一个值(即1)。而Card外部的count是在循环渲染时直接求值,因此能显示正确的0和1。

解决方案

方案1:拆分循环项为独立子组件(推荐)

把每个Card和对应的Offcanvas逻辑提取成单独子组件,让每个子组件持有自己的count(当前项索引)状态,从根源避免闭包问题:

// 子组件
const ChartCard = ({ count }) => {
  const [show, setShow] = useState(false);
  return (
    <>
      <Card>
        <Card.Body>
          <Button variant="primary" onClick={() => setShow(true)}>
            Modify Chart{count}
          </Button>
          <Offcanvas show={show} onHide={() => setShow(false)}>
            <Offcanvas.Header closeButton>
              <Offcanvas.Title>Modify Chart{count}</Offcanvas.Title>
            </Offcanvas.Header>
            <Offcanvas.Body>
              {count === 0 
                ? geo.map((item, index) => <Switch key={index} type={item} />)
                : productTypes.map((item, index) => <Switch key={index} type={item} />)
              }
            </Offcanvas.Body>
          </Offcanvas>
        </Card.Body>
      </Card>
    </>
  );
};

// 父组件中调用
{[0, 1].map(count => (
  <ChartCard key={count} count={count} />
))}

方案2:用闭包捕获当前循环的count值

如果不想拆分组件,可在循环内部通过闭包锁定每一次迭代的count快照:

{[0, 1].map(count => {
  // 闭包捕获当前count值
  const currentCount = count;
  return (
    <Card key={currentCount}>
      <Card.Body>
        <Button variant="primary" onClick={() => setShow(true)}>
          Modify Chart{currentCount}
        </Button>
        <Offcanvas show={show} onHide={() => setShow(false)}>
          <Offcanvas.Header closeButton>
            <Offcanvas.Title>Modify Chart{currentCount}</Offcanvas.Title>
          </Offcanvas.Header>
          <Offcanvas.Body>
            {currentCount === 0 
              ? geo.map((item, index) => <Switch key={index} type={item} />)
              : productTypes.map((item, index) => <Switch key={index} type={item} />)
            }
          </Offcanvas.Body>
        </Offcanvas>
      </Card.Body>
    </Card>
  );
})}

方案3:普通for循环改用let声明变量

如果外层是普通for循环而非map,将循环变量的var改为let——let会为每一次迭代创建独立作用域,确保内部引用的是当前迭代的count:

for (let count = 0; count < 2; count++) {
  // 此处渲染Card和Offcanvas的逻辑,内部count为当前迭代的独立值
}

关键说明

核心要保证Offcanvas内部引用的count是当前循环项的快照值,而非循环结束后的最终值。拆分组件的方案逻辑最清晰、易维护,优先推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:45:30