admin管理员组

文章数量:1327581

I am new to React and am probably lacking the correct terminology to find a solution to my problem. It cannot be that hard.

I am building a simple app which displays a set of questions, one question at a time. After answering one question, the next question is shown.

I have a ponent Question that renders 3 checkboxes, each checkbox represents one possible answer to the Question.

{this.props.question.answers.map((answer, index) => {
  return (
    <li className="Question__answer" key={answer.id}>
      <label className="Question__answer-label">
        <input
          className="Question__answer-checkbox"
          type="checkbox"
          value={index}
          onChange={this.props.setAnswer}
          defaultChecked={false} />
        {answer.answer}
      </label>
    </li>

    ...

    <button className="Question__next" type="button" onClick={this.props.onNext} disabled={this.props.isDisabled}>
        Next question
      </button>
  )
})}

Inside my main ponent Quiz I call the ponent like this:

<Question step={this.state.step} question={this.state.questions[this.state.step]} setAnswer={this.setAnswer} onNext={this.onNext} isDisabled={this.isDisabled()} />

onNext is my function which increments this.state.step in order to display the next question:

onNext(event) {
    this.setState({step: this.state.step + 1});
}

Everything works fine, except: When the next question is displayed, I want all 3 checkboxes to be unchecked again. Currently they remember their checked state from the previously answered question.

I am new to React and am probably lacking the correct terminology to find a solution to my problem. It cannot be that hard.

I am building a simple app which displays a set of questions, one question at a time. After answering one question, the next question is shown.

I have a ponent Question that renders 3 checkboxes, each checkbox represents one possible answer to the Question.

{this.props.question.answers.map((answer, index) => {
  return (
    <li className="Question__answer" key={answer.id}>
      <label className="Question__answer-label">
        <input
          className="Question__answer-checkbox"
          type="checkbox"
          value={index}
          onChange={this.props.setAnswer}
          defaultChecked={false} />
        {answer.answer}
      </label>
    </li>

    ...

    <button className="Question__next" type="button" onClick={this.props.onNext} disabled={this.props.isDisabled}>
        Next question
      </button>
  )
})}

Inside my main ponent Quiz I call the ponent like this:

<Question step={this.state.step} question={this.state.questions[this.state.step]} setAnswer={this.setAnswer} onNext={this.onNext} isDisabled={this.isDisabled()} />

onNext is my function which increments this.state.step in order to display the next question:

onNext(event) {
    this.setState({step: this.state.step + 1});
}

Everything works fine, except: When the next question is displayed, I want all 3 checkboxes to be unchecked again. Currently they remember their checked state from the previously answered question.

Share Improve this question asked Aug 30, 2016 at 12:07 mazemaze 2,2849 gold badges26 silver badges31 bronze badges 1
  • Possible duplicate of How to invoke a function in parent ponent from deeply nested child ponent using redux – Md.Estiak Ahmmed Commented Aug 30, 2016 at 12:19
Add a ment  | 

2 Answers 2

Reset to default 2

So the thing is that React renders its ponents such that only the ponents that changed are rendered. Since nothing has changed about the checkboxes checked attribute after rerendering they stay in their previous state.

What you should do is toggle the checkbox state on click in the setAnswer function and pass this as a prop to the Question ponent.

Something like

this.state {
   checkedAttr: ["false", "false", "false"]
} 

Pass it on like

<Question step={this.state.step} question={this.state.questions[this.state.step]} setAnswer={this.setAnswer} onNext={this.onNext} isDisabled={this.isDisabled()} checkedAttr={this.state.checkedAttr} />

Use them in the checkboxes state as

{this.props.question.answers.map((answer, index) => {
  return (
    <li className="Question__answer" key={answer.id}>
      <label className="Question__answer-label">
        <input
          className="Question__answer-checkbox"
          type="checkbox"
          value={index}
          checked={this.props.checkedAttr[index]}
          onChange={this.props.setAnswer}
          defaultChecked={false} />
        {answer.answer}
      </label>
    </li>

    ...

    <button className="Question__next" type="button" onClick={this.props.onNext} disabled={this.props.isDisabled}>
        Next question
      </button>
  )
})}

In the onNext function just reset the states checkedAttr to false.

On the Question Component use the ponentWillReceiveProps method like this:

ponentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

According to the docs :

ponentWillReceiveProps will be Invoked when a ponent is receiving new props. This method is not called for the initial render.

fetch the received step from the Question ponent and update its state to show the new Question.

本文标签: javascriptChange checked attribute of controlled checkbox (React)Stack Overflow