Reputation: 2284
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 component 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 component Quiz
I call the component 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.
Upvotes: 3
Views: 21283
Reputation: 281734
So the thing is that React renders its components such that only the components 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 component.
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
.
Upvotes: 2
Reputation: 780
On the Question
Component use the componentWillReceiveProps
method like this:
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
According to the docs :
componentWillReceiveProps will be Invoked when a component is receiving new props. This method is not called for the initial render.
fetch the received step from the Question
component and update its state to show the new Question
.
Upvotes: 0