简体   繁体   中英

concat vs push in react js

I am pretty new to React. I am not understanding why is this issue not working. I have Numbers Component .

const Numbers = (props) => {
  return(
    <div className="card text-center">
        <div>
        {Numbers.list.map((num,i) => 
            <span key={i} onClick={() => props.selectNumbers(num)}>
            {num}
          </span>
        )}
      </div>
    </div>
  );
}

Numbers.list = [1,2,3,4,5,6,7,8,9];

Now in the parent Game component ..

class Game extends React.Component {

    state = {
    selectedNumbers : []
  };

  selectNumber = (clickedNumber) => {
    if(this.state.selectedNumbers.indexOf(clickedNumber) >= 0) {return;}
    this.setState(prevState => ({
        selectedNumbers: prevState.selectedNumbers.concat(clickedNumber)
    }));
  };


    render() {
    const {selectedNumbers } = this.state;
    return (
        <div className="container">
        <h3>
            Play Nine
        </h3>
        <hr />
        <div className="row">
          <Answer selectedNums = {selectedNumbers} />
        </div>
        <br />
        <Numbers selectNumbers={this.selectNumber} selectedNums = {selectedNumbers} />
      </div>
    );
  }
}

Now, this thing works fine. But when I do ...

this.setState(prevState => ({
        selectedNumbers: prevState.selectedNumbers.push(clickedNumber)
    }));

the application does work as expected.

As prevState.selectedNumbers is an array should not it be push rather than concat ? What am I doing wrong?

In few words:

Array.prototype.push() adds an element into original array and returns an integer which is its new array length .

Array.prototype.concat() returns a new array with concatenated element without even touching in original array. It's a shallow copy.

When you use push , you are setting selectedNumbers to be the return value of the push operation, which is the length of the new array according to the mozilla developer docs . Push also attempts to mutate the array in state, which as PhilippSpo said doesn't work.

Either use concat as you were before or copy the selectedNumbers to a new array, push your value into that one, and then set selectedNumbers to the new array. If you're using ES6 you can use the spread operator as other users have pointed out

As mentioned in the comments push is a mutating function and returns the length of the resulting array. You can use the spread syntax to easily push a new item.

this.setState(prevState => ({
        selectedNumbers: [...prevState.selectedNumbers, clickedNumber]
    }));

You should use concat() function in place of push() because react does not work good with object mutability react people emphasize react developers to keep the state of immutable.

When you use concat() function it always returns a new object rather than mutating the same old object that is why you should never use push() function in react because push mutates the old object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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