javascript - this.setState isn't working (my state is a number) - Stack Overflow

I am having a problem with: this.setState({score: counter}); For some reason it's not updating. Wh

I am having a problem with: this.setState({score: counter}); For some reason it's not updating. Why? Even when I do this.setState({score: 5}) or score:"a string" it still doesn't work. Am I missing something? Whatever I do, the state won't change. I have to add extra description because the website won't let me post my question.

displayResultsHandler = () => {
    var counter = 0;
    for(let i = 0; i < this.state.correctAnswers.length; i++) {
      if(this.state.correctAnswers[i] === this.state.userAnswers[i]) {
        counter = counter+1;
      }
    }

this.setState({
  score: counter
});

console.log("counter: " + counter);
console.log("score: " + this.state.score); // For some reason, this is always zero

}

I added my full code below. Maybe it will help.

import React, { Component } from 'react';
import './App.css';
import Title from './Title/Title';
import Question from './Question/Question';
import Aux from './hoc/Aux';
import SubmitButton from './SubmitButton/SubmitButton';

class App extends Component {
  state = {
    questionArray: [
      "What is 9+10",
      "How many goals did Ronaldo score against Spain in the World Cup 2018",
      "Who Stole Ronaldo's (CR7) greates ever goal?",
      "Which one of these players ruined the NBA",
      "Who is currently number 1 in the internet L rankings?"
  ],
    answerChoicesArray: [
      ["1", "19", "21", "90", "-1"],
      ["1", "3", "5", "0", "-1"],
      ["Pepe", "Messi", "Casillas", "Benzema", "Nani"],
      ["Allen Iverson", "Kevin Durant", "Steph Curry", "Lebron James", "Russel Westbrook"],
      ["Drake", "Pusha T", "Russel Westbrook", "Lil Xan", "Russ"]
    ],

    correctAnswers: ["21", "3", "Nani", "Kevin Durant", "Russ"],

    userAnswers: ["", "", "", "", ""],

    score: 0

  }

  updateUserAnswersHandler = (oldArray, index, value) => {
    const newArray = oldArray;
    newArray[index] = value;
    this.setState({
      userAnswers: newArray
    });
  }

  displayResultsHandler = () => {
    var counter = 0;
    for(let i = 0; i < this.state.correctAnswers.length; i++) {
      if(this.state.correctAnswers[i] === this.state.userAnswers[i]) {
        counter = counter+1;
      }
    }

    this.setState({
      score: counter
    });

    console.log("counter: " + counter);
    console.log("score: " + this.state.score); // For some reason, this is always zero

    if(this.state.score < 5) {
      alert("You're dumb asf. Please leave");
    } else {
      alert("Wele to NASA");
    }
  }

  render() {
    // var userAnswers;
    // console.log(userAnswers); How do I pass this as a prop? this.userAnswers? nope. Therefore it has to be a state
    console.log("User Answers are: " + this.state.userAnswers);
    return (
      <div className="App">
        <div className="container">
          
            <Title/>
            <h2>Only the most genius of individuals will pass</h2>
            <hr/>
            <Question
              correctAnswers={this.state.correctAnswers}
              updateUserAnswersHandler={this.updateUserAnswersHandler}
              userAnswers={this.state.userAnswers}
              questionArray={this.state.questionArray}
              answerChoicesArray={this.state.answerChoicesArray} />
            <SubmitButton
              clicked = {this.displayResultsHandler} />
        </div>
      </div>
    );
  }
}

export default App;
<script src=".1.0/react.min.js"></script>
<script src=".1.0/react-dom.min.js"></script>

I am having a problem with: this.setState({score: counter}); For some reason it's not updating. Why? Even when I do this.setState({score: 5}) or score:"a string" it still doesn't work. Am I missing something? Whatever I do, the state won't change. I have to add extra description because the website won't let me post my question.

displayResultsHandler = () => {
    var counter = 0;
    for(let i = 0; i < this.state.correctAnswers.length; i++) {
      if(this.state.correctAnswers[i] === this.state.userAnswers[i]) {
        counter = counter+1;
      }
    }

this.setState({
  score: counter
});

console.log("counter: " + counter);
console.log("score: " + this.state.score); // For some reason, this is always zero

}

I added my full code below. Maybe it will help.

import React, { Component } from 'react';
import './App.css';
import Title from './Title/Title';
import Question from './Question/Question';
import Aux from './hoc/Aux';
import SubmitButton from './SubmitButton/SubmitButton';

class App extends Component {
  state = {
    questionArray: [
      "What is 9+10",
      "How many goals did Ronaldo score against Spain in the World Cup 2018",
      "Who Stole Ronaldo's (CR7) greates ever goal?",
      "Which one of these players ruined the NBA",
      "Who is currently number 1 in the internet L rankings?"
  ],
    answerChoicesArray: [
      ["1", "19", "21", "90", "-1"],
      ["1", "3", "5", "0", "-1"],
      ["Pepe", "Messi", "Casillas", "Benzema", "Nani"],
      ["Allen Iverson", "Kevin Durant", "Steph Curry", "Lebron James", "Russel Westbrook"],
      ["Drake", "Pusha T", "Russel Westbrook", "Lil Xan", "Russ"]
    ],

    correctAnswers: ["21", "3", "Nani", "Kevin Durant", "Russ"],

    userAnswers: ["", "", "", "", ""],

    score: 0

  }

  updateUserAnswersHandler = (oldArray, index, value) => {
    const newArray = oldArray;
    newArray[index] = value;
    this.setState({
      userAnswers: newArray
    });
  }

  displayResultsHandler = () => {
    var counter = 0;
    for(let i = 0; i < this.state.correctAnswers.length; i++) {
      if(this.state.correctAnswers[i] === this.state.userAnswers[i]) {
        counter = counter+1;
      }
    }

    this.setState({
      score: counter
    });

    console.log("counter: " + counter);
    console.log("score: " + this.state.score); // For some reason, this is always zero

    if(this.state.score < 5) {
      alert("You're dumb asf. Please leave");
    } else {
      alert("Wele to NASA");
    }
  }

  render() {
    // var userAnswers;
    // console.log(userAnswers); How do I pass this as a prop? this.userAnswers? nope. Therefore it has to be a state
    console.log("User Answers are: " + this.state.userAnswers);
    return (
      <div className="App">
        <div className="container">
          
            <Title/>
            <h2>Only the most genius of individuals will pass</h2>
            <hr/>
            <Question
              correctAnswers={this.state.correctAnswers}
              updateUserAnswersHandler={this.updateUserAnswersHandler}
              userAnswers={this.state.userAnswers}
              questionArray={this.state.questionArray}
              answerChoicesArray={this.state.answerChoicesArray} />
            <SubmitButton
              clicked = {this.displayResultsHandler} />
        </div>
      </div>
    );
  }
}

export default App;
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

Share Improve this question asked Jul 26, 2018 at 9:44 DonatDonat 1014 silver badges13 bronze badges 2
  • Have you added constructor in class ? – Rohan Veer Commented Jul 26, 2018 at 9:47
  • No. I thought we didn't need constructors in the newest version? Because I was able to change my userAnswers state without a constructor – Donat Commented Jul 26, 2018 at 9:50
Add a ment  | 

2 Answers 2

Reset to default 4

State updates are asynchronous. Your call to setState just queues the update, it doesn't make it happen immediately.

You're also using the wrong overload of setState (you're not alone, lots of people do!). When you're setting new state based on existing state, you cannot use the version that just accepts an object. You must use the callback version. If you want to use the resulting state when you're done, you can pass a second function which will be called when the state update is plete:

displayResultsHandler = () => {
    this.setState(
        // Updater
        prevState => {
            var counter = 0;
            for(let i = 0; i < prevState.correctAnswers.length; i++) {
              if(prevState.correctAnswers[i] === prevState.userAnswers[i]) {
                counter = counter+1;
              }
            }
            return {score: counter};
        },
        // Completion callback
        () => {
            console.log("score: " + this.state.score);
        }
    );
};

However, the documentation says this about using the pletion callback:

Generally we remend using ponentDidUpdate() for such logic instead.

This is all covered on this page of the documentation, and in the setState API docs.


Just as a side note, a couple of advanced JavaScript features (destructuring and shorthand property notation) and a prosaic one (increment operator) can make that code a bit more concise:

displayResultsHandler = () => {
    this.setState(
        // Updater
        ({correctAnswers, userAnswers}) => {                  // *** Destructuring
            let score = 0;
            for (let i = 0; i < correctAnswers.length; i++) {
              if (correctAnswers[i] === userAnswers[i]) {
                ++score;                                      // *** Increment
              }
            }
            return {score};                                   // *** Shorthand property
        },
        // Completion callback
        () => {
            console.log("score: " + this.state.score);
        }
    );
};

Some people might even use reduce instead of that for loop; I'm not convinced readability isn't impacted, though:

displayResultsHandler = () => {
    this.setState(
        // Updater
        ({correctAnswers, userAnswers}) => ({
            score: correctAnswers.reduce(
                (score, answer, index) =>
                    score + (answer === userAnswers[index] ? 1 : 0),
                0
            )
        }),
        // Completion callback
        () => {
            console.log("score: " + this.state.score);
        }
    );
};

(You could even drop the conditional operator and just use score + (answer === userAnswers[index]) since true coerces to 1 and false coerces to 0, but...)

this.setState is an asynchronous function.

try this -

this.setState({
  score: counter
},function(){
  console.log(this.state.score)
})

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745433096a4627482.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信