繁体   English   中英

setState在反应中使用索引更新数组值

[英]setState update array value using index in react

我想使用索引更新数组值,下面的代码可以吗?

handleChange = index => e => {
  const { rocket } = this.state // ['tesla', 'apple', 'google']
  rocket[index] = e.target.value
  this.setState({ rocket })
}

我的jsx

<div>{rocket.map((val,i) => <input type="text" onChange={handleChange(i)} value={val} />)}</div>

我知道它是可行的,但是只是为了确保可以像这样改变状态是可以的。

这样改变状态是不行的。

下一行以当前状态更改数组的方式,这可能导致程序中的错误,尤其是使用该状态的组件树下的组件。
这是因为状态仍然是相同的数组。

rocket[index] = e.target.value
//console.log(this.state.rocket) and you see that state is updated in place

始终将状态视为不变

您可以通过书面形式对此进行补救。

const newRocket = [
  ...rocket.slice(0, index),
  e.target.value, 
  ...rocket.slice(index + 1)
]

这样,当React进行对帐时,可以创建一个新数组并可以更新Component树中的组件。

注意
更改状态的唯一方法应该是通过调用Component.setState

现在有了新数组,您可以像下面这样更新组件状态:

this.setState({ rocket: newRocket })

可以使用Array.prototype.splice()代替更改现有值。

splice()方法通过删除现有元素和/或添加新元素来更改数组的内容。

 var arr= ['A','B','E','D']; arr.splice(2,1,'C') console.log(arr)//The result will be ['A','B','C','D']; 
 .as-console-wrapper {max-height: 100% !important;top: 0;} 

Stackblitz演示


代码片段

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'Demo using Array.prototype.slice()',
      rocket: ['tesla', 'apple', 'google'],
      link: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice'
    };
  }

  handleChange(index, e) {
    const { rocket } = this.state;
    rocket.splice(index, 1, e.target.value)
    this.setState({ rocket: [...rocket] }, () => {
      //call back function of set state you could check here updated state
      console.log(this.state.rocket)
    });
  }

  render() {
    return (
      <div>
        <b><a target="_blank" href={this.state.link}>{this.state.name}</a></b>
        {
          this.state.rocket.map((val, i) =>
            <p key={i}>
              <input type="text" onChange={(e) => { this.handleChange(i, e) }} value={val} />
            </p>)
        }</div>
    );
  }
}

render(<App />, document.getElementById('root'));

暂无
暂无

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

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