在循环中创建多个 React 组件时,递增计数器作为 prop 传递时,为什么计数器显示最终值?

When creating multiple React Components in a loop with an incrementing counter passed as a prop, why does the counter show the final value?

我正在尝试了解闭包在 javascript 中的工作原理。

在这里,我使用 foreach 遍历 'items' 数组的值。我在 foreach 循环的范围之外声明了一个 let 变量“count”。每次迭代后,'item' 的值被添加到 'count'。在循环内,我声明了一个新的 React 组件,它呈现“count”的值。



export default function App() {
  const comps: ComponentType<any>[] = [];

  let count = 0;
  const items = [5, 1, 3];

  items.forEach((item) => {
    const countCopy = count;
    comps.push((props) => (
      <div>
        {count} : {countCopy}
      </div>
    ));
    count += item;
  });

  return (
    <div className="App">
      {comps.map((Comp) => (
        <Comp />
      ))}
    </div>
  );
}

但是当我 运行 代码时,显示的计数值是它的最后一个值 (9)。我需要创建变量的副本“countCopy”以显示其当前值。这是为什么?有更清洁的方法吗?

代码沙箱:

https://codesandbox.io/s/javascript-closure-question-5uwmm

我找到了一个使用 reduce 而不是 foreach 的解决方案:

export default function App() {
  const comps: ComponentType<any>[] = [];

  const items = [5, 1, 3];

  items.reduce<number>((count, item) => {
    const countCopy = count;
    comps.push((props) => (
      <div>
        {count} : {countCopy}
      </div>
    ));
    return count + item;
  }, 0);

  return (
    <div className="App">
      {comps.map((Comp) => (
        <Comp />
      ))}
    </div>
  );
}

呈现的“计数”确保为当前值,因为它是在循环内声明的

https://codesandbox.io/s/javascript-closure-question-solution-8ping