我有一种感觉,这是一个"错误"的问题,但无论如何都要进行:
我正在制作某种测验应用程序(使用redux进行状态管理).(在这里显示重要的位)
quiz.js
<Slider {...sliderSettings} slideIndex={currentQuestionIndex}>
<Start onStart={() => onNextQuestion()} topicId={topicId} />
{
questions.map((question, ndx) => {
return (
<Question {...question} done={onDone} key={`question-${question.id}`} />
);
})
}
<Result score={score} onRestart={() => onRestart()}/>
</Slider>
Run Code Online (Sandbox Code Playgroud)
question.js
<div className="question">
<h2 className="question__text">{ question }</h2>
<MultipleChoice options={answers} onChange={done} />
</div>
Run Code Online (Sandbox Code Playgroud)
多choice.js
const
initialState = {
selectedValue: null
};
class MultipleChoice extends Component {
constructor(props) {
super(props);
this.state = initialState;
}
handleChange(value, correct) {
this.setState({
selectedValue: value
});
this.props.onChange(correct);
}
render() {
const
{ options } = this.props,
getStateClass = (option, ndx) => {
let sc = '';
if (this.state.selectedValue !== null) {
if (this.state.selectedValue === ndx) {
sc = option.correct ? 'is-correct' : 'is-incorrect';
} else if (option.correct) {
sc = 'is-correct';
}
}
return sc;
};
return (
<ul className="multiple-choice">
{ options.map((option, ndx) => {
return (
<li key={`option-${ndx}`} className={cx('multiple-choice__option', getStateClass(option, ndx))}>
<button className="multiple-choice__button" onClick={() => this.handleChange(ndx, option.correct)}>{option.answer}</button>
</li>
);
}) }
</ul>
);
};
}
export default MultipleChoice;
Run Code Online (Sandbox Code Playgroud)
问题在于MultipleChoice的渲染.它使用内部状态来显示哪个答案是错误的和正确的.
在quiz.js中,onRestart调度一个redux动作,该动作更新存储以获取一些新问题并将currentQuestionIndex重置为0.这一切都有效.但不知何故,有时候MultipleChoice元素被"重用",并且仍在显示它在上一轮问题中的状态.换句话说,大多数情况下会安装新的MultipleChoice,但有时却不是.如果我理解正确,这是反应和解吗?
但是我该如何解决这个问题呢?在我看来,MultipleChoice需要它的内部状态.所以我应该以某种方式重置这个状态?或者确保每次都安装一个新的MultipleChoice?或者我在这里问错了问题?
Dan*_*mov 15
我查看了您的存储库,问题正如另一个答案中正确指出的那样,您的<Question>(以及内部<MultipleChoice>)组件永远不会卸载,因此它们保持状态.
通常情况下,这在React中并不常见,因为人们通常希望在组件位于树中时保留状态.当不再需要状态时,人们通常会停止在render()方法中包含组件,并且React会卸载它们.下次渲染时,状态会重置.
国家是否未得到你的榜样复位,因为你永远保持<Question>有形之,甚至测验运行之间.您可以看到<Question>在我们开始测验之前已经安装了s,并在结束后保持挂载状态:
那么我们如何强迫React重置他们的状态呢?有三种选择:
您可以让它们卸载.下次他们上架时,他们会有一个新的状态.这通常是最简单的解决方案,因为您实际上并未在初始"开始测验"页面上显示问题.例如,你可以通过在方法中currentQuestionIndex > 0 &&渲染之前添加guard 来实现.questions.map(...)render()<Questions>
您可以将新keys 传递给与之前的keys 不匹配的新s.您目前正在使用question-${question.id},key但即使您重试测验,也会为同一个问题生成相同的密钥.要解决此问题,您可以引入一个新的状态变量(例如,在Redux或顶级组件状态中)quizAttemptIndex,并在任何新尝试时递增它.然后你可以改变密钥question-${quizAttemptIndex}-${question.id}.这种方式再次尝试测验会重置问题的内部状态(以及使其重新安装).
最后,如果你不想通过传递一个不同的key东西来完全破坏DOM ,你可以通过quizAttemptIndex(在上一节中解释)作为道具<MultipleChoice>.然后,在它里面,你可以this.setState({ selectedValue: null })里面componentWillReceiveProps(nextProps)如果nextProps.quizAttemptIndex !== this.props.quizAttemptIndex.
您可以选择任一解决方案,具体取决于您始终保持问题的重要性.
| 归档时间: |
|
| 查看次数: |
943 次 |
| 最近记录: |