反应列表组件事件中的变量

Variable in event of react list component

这是我的代码:

export default function App() {
  const array = ["item1", "item2", "item3"];
  let progress = "";
  const list = array.map((item) => {
    progress += `/${item}`;
    return (
      <input
        key={item}
        type="button"
        value={item}
        onClick={() => {
          console.log(progress);
        }}
      />
    );
  });
  return <div className="App">{list}</div>;
}

另外,你可以在sandbox

上试试

当我点击页面上的 item1 按钮时。为什么控制台日志 /item1/item2/item3?

预期的行为是:

当 item1 按钮被点击时。控制台日志 /item1;

当 item2 按钮被点击时。控制台日志 /item1/item2;

...

谢谢。

当您单击该按钮时,您提供的箭头功能将会触发。这意味着该函数将仅在调用箭头函数时读取变量。由于进度变量不是在映射或箭头函数内部创建的,而是在其外部创建的,因此最后映射的输入元素会将其设置为 item1item2item3,这意味着当您单击每个输入时它将相同.

要解决此问题,您可以在 map 方法中分配一个等于进度的局部变量,如下所示:

export default function App() {
  const array = ["item1", "item2", "item3"];

  let progress = "";

  const list = array.map((item) => {
    progress += item;
    let local = progress;
    return (
      <input
        key={item}
        type="button"
        value={item}
        onClick={() => {
          console.log(local);
        }}
      />
    );
  });
  return <div className="App">{list}</div>;
}

我还没有完全测试过,但应该可以。

执行代码时,array.map 方法会运行为数组的每个元素提供的回调函数。因此,当您的程序完成执行时,progress 的值将是 item1item2item3 并且您所有的点击处理程序都关闭了同一个变量 progress(在闭包中保留对变量的引用)因此结果 item1item2item3.

您可以通过使用 IIFE 为每个处理程序定义一个新范围来解决这个问题。


export default function App() {
  const array = ["item1", "item2", "item3"];
  var progress = "";
  const list = array.map(function (item) {
    progress += item;
    return (
      <input
        key={item}
        type="button"
        value={item}
        onClick={(function(progress){
          return function () {
            console.log(progress);
          }
        })(progress)}
      />
    );
  });
  return <div className="App">{list}</div>;
}```