简体   繁体   English

当在循环中创建多个 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?

I'm trying to understand how closures work in javascript.我试图了解闭包在 javascript 中是如何工作的。

Here, I'm iterating through values of the 'items' array using a foreach.在这里,我使用 foreach 遍历“items”数组的值。 I've a let variable "count" declared outside the scope of the foreach loop.我在 foreach 循环的范围之外声明了一个 let 变量“count”。 After each iteration, the value of 'item' is added to 'count'.每次迭代后,'item' 的值被添加到'count'。 Inside the loop, I'm declaring a new React Component that renders the value of "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>
  );
}

But when I run the code, the count value that is showed is its last value (9).但是当我运行代码时,显示的计数值是它的最后一个值 (9)。 I need to create a copy "countCopy" of the variable in order to display its current value.我需要创建变量的副本“countCopy”以显示其当前值。 Why is that?这是为什么? Is there a cleaner way?有更干净的方法吗?

CodeSandbox:代码沙盒:

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

I've found a solution using reduce instead of foreach:我找到了一个使用 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>
  );
}

The "count" that is rendered is assured to be the current value, since it is declared inside the loop渲染的“计数”确保是当前值,因为它是在循环内声明的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM