开发者问题收集

React 状态中的增量和减量数组计数器

2022-06-15
553

我很难弄清楚为什么我无法正确地增加/减少数组中的四个计数器,该数组处于应用程序状态。状态中的数组是这样的:

...
constructor(props) {
    super(props);
    
    this.state = {
      right: 0,
      left: 0,
      up: 0,
      down: 0,
      ...more variables... 
      bank: [0, 0, 0, 0] // <- array with 4 counters set to zero
      };
 }
 ...

应用程序从 Node.js 服务器获取 JSON 数据,并将传入数据保存在状态中可以看到的“左”、“右”、“上”和“下”变量中。我选择应该增加/减少哪个计数器(我称之为“bank”),读取“左”和“右”JSON 数据,并使用“上”和“下”进行增加或减少。这些信号工作正常,但我认为问题出在逻辑上。 这是处理 bank 选择(计数器)的函数:

bankSelection() {
    if (parsedJsonData.right) {
      currentBank += 1;
      if (currentBank > maxBank) { // restart from zero
        currentBank = 0;
      }
    } else if (parsedJsonData.left) {
      currentBank -= 1;
      if (currentBank < 0) { // restart from 3
        currentBank = 3;
      }
    }
  }

我没有将 bank 值保存在状态中,因为它不应该被渲染。问题出在增量/减量函数上:

updateCounters() {
    if (parsedJsonData.up) {
      if (this.state.bank[currentBank] < 9) {
        let bankValue = this.state.bank[currentBank] + 1;
        this.setState({ bank: bankValue });
      } else {
        this.setState({ bank: this.state.bank[currentBank] = 0 });
      }
    } else if (parsedJsonData.down) {
      if (this.state.bank[currentBank] > 0) {
        let bankValue = this.state.bank[currentBank] - 1;
        this.setState({ bank: bankValue });
      } else {
        this.setState({ bank: this.state.bank[currentBank] = 9 });
      }
    }
  }

我看到 React 引擎在第 7 行和第 14 行抱怨,说我不应该直接改变状态,但我在 setState 函数里面! 除此之外,当我发送如下格式的 JSON 时:

{
    "left": 0,
    "right": 0,
    "up": 1,
    "down": 0
}

第一次,第一个库中的计数器正确更新并显示值 1,但第二次在浏览器的控制台中收到此错误:

Uncaught (in promise) TypeError: Cannot create property '0' on number '1'
    at App.updateCounters (App.js:145:1)
    at App.js:112:1

我尝试了很多解决方案,我快要疯了,任何帮助我都会很感激... 您可以在这里找到 完整代码 ,但请记住,它仍然是渲染方法中的一项正在进行的工作(第一个库是唯一可用的,仍在测试各种解决方案)。 我希望我给你所有的信息来帮助我修复错误。

2个回答

我发现您的代码存在一些问题。

  1. bank 的值是数组。您尝试使用 this.setState({ bank: bankValue })
  2. 状态应该是不可变的,如果您希望更改值,则需要创建一个新数组并设置 bank 状态。类似这样:
this.setState({bank: Object.values({...this.state.bank, 1: 100}); // where 1 is the idx where you want to update the value, and 100 is the new value
Atul Patil
2022-06-15

最后,我设法解决了这个问题。 我使用扩展运算符并避免在 setState 方法内直接赋值来解决这个问题。

updateCounters() {
    if (parsedJsonData.up) {
      if (this.state.bank[currentBank] < 9) {
        // let bankValue = this.state.bank[currentBank] + 1;
        var newArrayUp = [...this.state.bank];
        newArrayUp[currentBank] += 1;
        console.log("array clonato dopo aggiornamento " + [...newArrayUp]);
        this.setState({ bank: [...newArrayUp] }, () => {
          this.forceUpdate();
        });
      } else {
        var zeroArray = [...this.state.bank];
        zeroArray[currentBank] = 0;
        console.log(zeroArray[currentBank]);
        this.setState({ bank: [...zeroArray] });
        this.forceUpdate();
      }
    } else if (parsedJsonData.down) {
      if (this.state.bank[currentBank] > 0) {
        var newArrayDown = [...this.state.bank];
        newArrayDown[currentBank] -= 1;
        console.log("array clonato dopo aggiornamento " + [...newArrayDown]);
        this.setState({ bank: [...newArrayDown] }, () => this.forceUpdate());
      } else {
        var nineArray = [...this.state.bank];
        nineArray[currentBank] = 9;
        console.log(nineArray[currentBank]);
        this.setState({ bank: [...nineArray] }, () => this.forceUpdate());
      }
    }
  }

现在我创建原始数组的副本,对其进行处理,然后将其传递给 setState 方法。 感谢您的建议!

furiopiccinini
2022-06-17