最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - setState update array value using index in react - Stack Overflow

programmeradmin4浏览0评论

I want to update array value using index, is below code ok?

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

my jsx

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

I know it worked, but just to be sure it's ok to mutate the state like that.

I want to update array value using index, is below code ok?

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

my jsx

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

I know it worked, but just to be sure it's ok to mutate the state like that.

Share Improve this question asked Oct 19, 2018 at 5:09 Melissa94Melissa94 4231 gold badge5 silver badges12 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

It's not okay to mutate state this way.

The following line mutates the array in the current state in a way that can lead to bugs in your program particularly with ponents down the Component tree using that state.
This is because the state is still the same array.

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

Always treat state as immutable

You can remedy this by writing.

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

This way a new array is created and ponents in the Component tree can be updated when React does a reconciliation.

Note that
The only way to mutate state should be through calls to Component.setState.

Now that you have a new array, you can update the ponent state like so:

this.setState({ rocket: newRocket })

Instead of changing existing value, you could use Array.prototype.splice().

The splice() method changes the contents of an array by removing existing elements and/or adding new elements.

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 demo


CODE SNIPPET

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'Demo using Array.prototype.slice()',
      rocket: ['tesla', 'apple', 'google'],
      link: 'https://developer.mozilla/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'));

you can try on this



  const onChangeProduct = (e, index) => {
    console.log("Value price " + e);
    const updateItem =  [...imports];
    updateItem[index]["product"] = e;
    setImports(updateItem);

  }



 <Select
         className="w-40"
            showSearch
            placeholder="Select product"
            optionFilterProp="children"      
            value={element.product}
            onChange= {(e) => onChangeProduct(e, index)}
            options={
                items
            }
          />





发布评论

评论列表(0)

  1. 暂无评论