首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >学习反应- ReferenceError

学习反应- ReferenceError
EN

Stack Overflow用户
提问于 2020-12-23 11:58:40
回答 2查看 74关注 0票数 1

从今天开始学习react,我遇到了一个可能与JS相关而不是实际反应的问题。

代码语言:javascript
复制
import React, { useState } from "react";
import Counter from "./counter";

function Counters() {
  const [counters, setCounters] = useState([
    { id: 1, value: 4 },
    { id: 2, value: 0 },
    { id: 3, value: 0 },
    { id: 4, value: 0 },
  ]);


  const handleDelete = (counterID) => {
    setCounters(counters.filter((counter) => counter.id !== counterID));
  };

  const handleIncrement = (counterToBeUpdated) => {
    console.log(counters);
    const counters = [...counters];
    const index = counters.indexOf(counterToBeUpdated);
    counters[index] = { ...counterToBeUpdated };
    counters[index].value++;
    setCounters({ counters });
  };

  return (
    <div>
      {counters.map((counter) => (
        <Counter
          key={counter.id}
          counter={counter}
          onDelete={handleDelete}
          onIncrement={handleIncrement}
        />
      ))}
    </div>
  );
}

export default Counters;

当子组件调用handleIncrement时,我会得到在初始化计数器之前尝试访问计数器的引用错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-23 12:24:16

这是因为您尝试使用外部作用域中同名的变量:const counters = [...counters];

代码语言:javascript
复制
const counters = [1, 2, 3];

function update() {
  const counters = [...counters];
}

update();
// => "Uncaught ReferenceError: Cannot access 'counters' before initialization"

您甚至不需要在增量处理程序中使用新的变量,您可以使用counters.map()来迭代元素并更新所需的值。返回的数组将是一个新数组,因此您可以将它传递给您的setCounters()函数。请查看下面的工作演示:

代码语言:javascript
复制
function Counter({ counter, onDelete, onIncrement }) {
  return (
    <div>
      <span style={{marginRight: '1rem'}}>{counter.value}</span>
      <button onClick={() => onIncrement(counter.id)}>Inc</button>
      <button onClick={() => onDelete(counter.id)}>Delete</button>
    </div>
  );
}

function Counters() {
  const [counters, setCounters] = React.useState([
    { id: 1, value: 4 },
    { id: 2, value: 0 },
    { id: 3, value: 0 },
    { id: 4, value: 0 },
  ]);

  const handleDelete = (id) => {
    setCounters(counters.filter((counter) => counter.id !== id));
  };

  const handleIncrement = (id) => {
    setCounters(
      counters.map((counter) =>
        counter.id === id ? { ...counter, value: counter.value + 1 } : counter
      )
    );
  };

  return (
    <div>
      {counters.map((counter) => (
        <Counter
          key={counter.id}
          counter={counter}
          onDelete={handleDelete}
          onIncrement={handleIncrement}
        />
      ))}
    </div>
  );
}

ReactDOM.render(<Counters />, document.getElementById('root'));
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

票数 3
EN

Stack Overflow用户

发布于 2020-12-23 12:39:49

我认为这里的主要问题是如何称呼handleIncrement。调用它时没有参数,这意味着counterToBeUpdated将是未定义的。

如果你把onIncrement={handleIncrement}改为onIncrement={() => handleIncrement(counter.id)},那就只有一半了。

handleIncrement中使用counters.indexOf(counterToBeUpdated)Array.indexOf()返回作为参数传递的值的数组位置。由于您正在寻找对象,而对象相等是javascript中的大话题,所以我建议您最好在这里使用Array.find()

这就是如何在数组中找到对象的方法。

代码语言:javascript
复制
const counterToBeUpdated = counters.find((counter) => counter.id === counterToBeUpdated);

由于此方法仍有许多工作要做(增量计数器,创建带有计数器的新数组,将此数组设置为状态),我将使用Array.map()向您展示一个快捷方式。

代码语言:javascript
复制
const handleIncrement = (counterToBeUpdated) => {
  setCounters(counters.map((counter) => {
    if(counter.id === counterToBeUpdated){
      return {
        ...counter,
        value: counter.value + 1
      };
    } else {
      return counter;
    }
  });
};

Array.map()返回一个新的数组。您传递的函数将对数组中的每个值执行,您将决定新数组中的适当值应该是什么样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65423947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档