0

Working on reactJS project, and I know we don't mutate the state (usually i don't but don't know the exact reason) so I just tried some wrong approach even its working correctly.

import logo from './logo.svg';
import './App.css';
import Test from './test';
import {Home, NotFoundComponent,Contact, Profile} from './test/home'
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom'
import React, {Component} from 'react';


class App extends Component {
  constructor(props) {
    super(props);
 
    this.state = {
      list: [42, 33, 68],
    };
  }
 
  onUpdateItem = i => {
    this.state.list[i]++;
    this.setState({
      list: this.state.list,
    })

    // this.setState(state => {
    //   const list = state.list.map((item, j) => {
    //     if (j === i) {
    //       return item + 1;
    //     } else {
    //       return item;
    //     }
    //   });
 
    //   return {
    //     list,
    //   };
    // });
  };
 
  render() {
    return (
      <div>
        <ul>
          {this.state.list.map((item, index) => (
            <li key={item}>
              The person is {item} years old.
              <button
                type="button"
                onClick={() => this.onUpdateItem(index)}
              >
                Make me one year older
              </button>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}



export default App;

this.state.list[i]++;
this.setState({
  list: this.state.list,
})

what is the problem with when I update the code above instead map method, both give the correct output?

explain to me this behind the scene code sandbox link

5
  • 1
    There's nothing wrong with your approach unless if your state is immutable. But be careful when you're working with reference types. But if you've children which dependent on parent list, it doesn't update the children. Commented Oct 25, 2020 at 3:27
  • cause both ref type is equal and content only differ so child cant recognizes It correct? Commented Oct 25, 2020 at 3:33
  • That's right!!! Commented Oct 25, 2020 at 3:46
  • 1
    I have created a example here. Check this out stackblitz.com/edit/react-wt5tf4?file=src%2FChild.js Commented Oct 25, 2020 at 4:07
  • bro, which react part knows both refs is same so we don't need to update UI, is render() or shoulcomponemtUpdate() life cycle Commented Oct 25, 2020 at 15:11

2 Answers 2

1

Here is the reason:

When you mutate an array, say list[i]++ the identity of the array is not changed so listBefore ==== listAfter, while you map over the array listBefore !== listAfter, when you invoke setState, ALL the children component will be invoked again by default even if you put nothing inside setState. Because react can not tell if the children update is necessary by default and it is a waste of resources actually.

You can prevent this from happening by telling the Children "Do NOT update" by calling shouldComponentUpdate or simply use PureComponent.

And the way to tell if updates are necessary is to compare using ===

In addition, Even if you do not care about performance. you should never do this. It will cause some debuggable bugs in some cases mainly because the updates in react is NOT synchronized. I never encounter by the way because I do not even dare to try

Sign up to request clarification or add additional context in comments.

2 Comments

if i update throgh this.state.list.map((value,index)=>{ means childern wont update?
@SelvaGanapathi the children will ALWAYS update by default even if you call setState({}) (empty object), you can confirm what I say by putting console.log in children
1

When you update your state you should take care of immutable.

onUpdateItem = i => {
  //this.state.list[i]++;
  //this.setState({
  //  list: this.state.list,
  //})
  this.setState({
    list: this.state.list.map((value,index)=>{
      if(i === index) return value+1;
      return value;
    })
  });
}

If you are not maintaining immutable, your app will not work what you expected.

React states are updated follow life-cycle. if without immutability, it means you are breaking the life-cycle.

2 Comments

I know, what if i am not maintaining immutable?
He asked why and you told him how

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.