1

I'm working on a quiz and I would like to make it so when the user clicks the correct answer it turns green if the user clicks the wrong answer it turns red.

This is what I got right now:

state = {
  answerClass: false,
};


handleVoting(answer) {
    if (answer == this.props.questions[this.props.questionIndex].answer) {
      this.setState({
        answerClass: 'green'
      });
    } else {
      this.setState({
        answerClass: 'red'
      });
    }

    var options = [];

    if (this.props.options) {
      for (var i = 0; i < this.props.options.length; i++) {
        options.push( < div className = {
            this.state.answerClass
          } >
          <
          img onClick = {
            this.handleVoting.bind(this, this.props.options.value)
          }
          src = {
            url
          }
          /></div > );
      }
    }

So this creates two image buttons for voting when I click on one of them I am sending a value to the handleVoting function that checks if the value clicked is the same as the answer to the question I am setting a state to the class name.

The issue with this is that if I click on the correct option both turn green and if I click on the wrong option it turns both red.

1
  • How does render() look like? Commented Oct 5, 2018 at 22:22

1 Answer 1

2

You're close! What's happening is that you are applying the same part of state to all buttons. All you need to do to fix this is have a separate part of state for each button. For this case, I would suggest an array to hold the state for each button. Then, you just need to pass the index of the option to your handleVoting function and use it to determine which part of the state to set.

Also, not sure if just copy/pasted incorrectly, but make sure that your state is assigned to the UI in a render method. I would also recommend using the map function when you are dynamically assigning an array.

See below...

state = {
  answerClasses: [],
};


handleVoting(answer, index) {
    if (answer == this.props.questions[this.props.questionIndex].answer) {
      let newAnswerClasses = this.state.answerClasses;
      newAnswerClasses[index] = 'green';
      this.setState({
        answerClasses: newAnswerClasses
      });
    } else {
      let newAnswerClasses = this.state.answerClasses;
      newAnswerClasses[index] = 'red';
      this.setState({
        answerClasses: newAnswerClasses
      });
    }
   }

render() {
    let options = this.props.options.map(function(option, i) {
       return (< div className = {
            this.state.answerClasses[i]
          } >
          <
          img onClick = {
            this.handleVoting.bind(this, this.props.options.value, i)
          }
          src = {
            url
          }
          /></div > );
    }.bind(this));
    return <div>{options}</div>

  }

EDIT for comment

state = {
  answerClasses: [],
};


handleVoting(answer, index) {
      let newAnswerClasses = this.state.answerClasses;
    if (answer == this.props.questions[this.props.questionIndex].answer) {
      newAnswerClasses[index] = 'green';
      this.setState({
        answerClasses: newAnswerClasses
      });
    } else {
      // for loop method
      for(let i=0; i < this.props.options.length; i++) {
        if(this.props.options[i].value === answer) {
          newAnswerClasses[i] = 'red';
          break;
        }
      }
      // OR passing index to component via props method
      newAnswerClasses[this.props.answerIndex] = 'green';
      newAnswerClasses[index] = 'red';
      this.setState({
        answerClasses: newAnswerClasses
      });
    }
   }

render() {
    let options = this.props.options.map(function(option, i) {
       return (< div className = {
            this.state.answerClasses[i]
          } >
          <
          img onClick = {
            this.handleVoting.bind(this, this.props.options.value, i)
          }
          src = {
            url
          }
          /></div > );
    }.bind(this));
    return <div>{options}</div>

  }

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

5 Comments

Thank you, this is great! May i ask if you know how i could make it so when i click on wrong answer it also adds the class "green" to the correct one.
No problem! Sure, to do that is a bit more complex, but definitely doable. You just need to know the index of the correct answer and do the same setting process as above. In the section of handleVoting where you handle the incorrect answer, add a for loop that loops through the this.props.options and compares each option's value to the correct answer. When you hit the correct answer, call newAnswerClasses[index in for loop] = 'green' and that should do the trick!
Or better yet, pass the index of the correct answer down in props from the parent component and ditch the for loop entirely.
Yeah i tried with loop option before but could not figure it out properly and it got a bit messy. Would you mind adding the new "better" option to your answer above so i can see what you mean ? Thanks
I've edited my answer with both the for loop and props method. If you are going to use the props method, you must find the index of the answer (which you might still have to find using a for loop) in your parent component and then pass it down to your voting component the same way you passed options down. Then, just add the line of code from above.

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.