将prevstate参数添加到this.setState会导致typeError

时间:2018-10-16 03:18:58

标签: javascript reactjs state typeerror setstate

我正在更新状态onchange。 setState可以在不提供prevstate的情况下工作,但是当然不会在其余状态值中写入。但是当我添加prevstate时,出现了此错误:

  

TypeError:无法读取未定义的属性“名称”

  110 | if(inputs[i].checked && this.state.rates[`${inputs[i].name}`] !== true ) {
  111 |   this.setState(prevstate=>({
  112 |     ...prevstate,
> 113 |     rates: {
      | ^  114 |       ...prevstate.rates,
  115 |       [inputs[i].name]: true
  116 |     }

我不知道是什么原因造成的。这是状态和我的handleChange函数:

this.state={
  rawnew:[],
  rawold:[],
  posts: [],
  count: 0,
  report: false,
  rates: {}
}

handleChange函数:

handleChange = (e) => {
  var inputs = document.getElementsByTagName('input')
  console.log(this.state)
  for (var i = 0; i < inputs.length; i++) {
    console.log(i, inputs[i].name)
    if (inputs[i].checked && this.state.rates[`${inputs[i].name}`] !== true) {
      this.setState(prevstate => ({
        ...prevstate,
        rates: {
          ...prevstate.rates,
          [inputs[i].name]: true
        }
      }))
    } else if (this.state.rates[`${inputs[i].name}`] !== undefined && this.state.rates[`${inputs[i].name}`] !== inputs[i].checked) {
      this.setState(prevstate => ({
        rates: {
          ...prevstate.rates,
          [inputs[i].name]: !prevstate.rates[`${inputs[i].name}`]
        }
      }))
    }
  }
}

1 个答案:

答案 0 :(得分:0)

setState是异步的,这意味着i的值可能在setState运行时已更改。这也意味着this.state可能在每次迭代中都不包含更新后的值。例如,当您检查名称的费率是否为真时:

this.state.rates[`${inputs[i].name}`] !== true

以前的迭代有可能将该值设置为true,但尚未更新this.state

与其在循环内更新状态,不如尝试建立新状态并在循环外更新一次。

使用forEach循环为每次迭代创建新的作用域,并确保input在运行setState时具有相同的内容。

handleChange = (e) => {
    // see Jesse's comment about using refs
    var inputs = document.getElementsByTagName('input'); 
    const newState = { ...this.state, rates: ...this.state.rates };

    inputs.forEach(input => {
        const { checked, name } = input;
        newState.rates[name] = checked;
    });

    this.setState(newState);
}