Why can't I push values in my state array in react.js?

前端 未结 5 938
后悔当初
后悔当初 2021-01-15 09:40

I can add 1 item to the array it logs [\"50\"] in the console. But when I try to add a second value I get this error \"currentScores.push is not a f

相关标签:
5条回答
  • 2021-01-15 10:21

    The problem is that push doesn't return a new array, bit the length of the amended array. So you're actually assigning state.stores to a number, which of course doesn't support push.

    I can see you're trying to avoid mutating state by attempting to clone the scores array, but push will mutate it, not return a new instance. It might be better to do something like:

    const newScores = [...this.state.scores, this.state.scoreInput];
    this.setState({ scores: newScores });
    
    0 讨论(0)
  • 2021-01-15 10:22

    The problem is over here <button onClick={this.addScore(this.state.scoreInput)}> add</button>);

    When you run this.addScore(this.state.scoreInput) inside the onclick, javascript runtime will call addScore function. Thats why you are getting 50~logs

    Try <button onClick={ function(){this.addScore(this.state.scoreInput)}}> add</button>);

    0 讨论(0)
  • 2021-01-15 10:23

    The return value of currentScores.push() is the new number of elements in the array. You then save this in your state which means that scores in your state becomes a number instead of an array.

    You likely want to construct a new array instead since you are working with constant variables:

    const currentScores = this.state.scores;
    const newScores = currentScores.concat(this.state.scoreInput);
    this.setState({ scores: newScores });
    
    0 讨论(0)
  • 2021-01-15 10:28

    Two things, when you make use of push it doesn't return a new array. Make use of concat and bind the value to the addUser function.

    Also wrap your elements inside a single div and write your console.log() statement to output the state value in the callback function of setState since it takes some time to mutate

     class Scores extends React.Component {
    
          constructor() {
            super();
            this.addScore = this.addScore.bind(this);
            this.handleScoreChange = this.handleScoreChange.bind(this);
            this.state = {
              scores: [],
              scoreInput: '',
            };
          }
    
          addScore() {
            const currentScores = this.state.scores;
            const newScores = currentScores.concat(this.state.scoreInput);
            this.setState({ scores: newScores }, function(){
              console.log(this.state.scores);
            });
            
          }
    
          handleScoreChange(e) {
            this.setState({ scoreInput: e.target.value });
          }
    
          render() {
            const scores = this.state.scores;
            return (
                    <div>
                    <input name="score" type="text" placeholder="Score" onChange={this.handleScoreChange}/>
                    <button onClick={this.addScore.bind(this, this.state.scoreInput)}>add</button></div>
            );
          }
        }
    
        ReactDOM.render(<Scores/>, document.getElementById('app'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="app"></div>

    0 讨论(0)
  • 2021-01-15 10:32

    Push returns the new length property of the object upon which the method was called.

    You set the state of scores to the new length each time.

    addScore() {
            console.log(this.state.scores);
            this.setState(state=> ({
                scores: [...state.scores, state.scoreInput]
                })
             );
          }
    
    0 讨论(0)
提交回复
热议问题