我是一个很新的反应者,正在构建一个测验反应应用程序。每个测验都有一个时间限制,该时间限制通过道具使用https://github.com/ndresx/react-countdown
通过道具传递给倒数计时器组件我将以秒为单位存储时间,并以父组件的状态存储从4个选项中选择的答案。
问题是,每次我调用setState
并从孩子那里获得所选答案时,计时器都会重新启动为初始状态,因为整个组件都会重新显示(例如,测验从03:00分钟开始,计时器同时倒计时至02:00,然后用户选择答案,计时器重置为03:00)
我尝试在父级中实现shouldComponentUpdate
来检查当前时间是否等于初始时间,但是它阻止了对整个页面的任何状态更新(存储在状态中的答案标记为所选答案)。我也尝试在父级上使用PureComponent
,但这并没有改变问题。
某些代码:
具有selectAnswer
功能的父组件,该组件设置状态并对此问题负责(道具的来源来自路由重定向)
class ExamWindow extends Component {
constructor(props) {
super(props);
this.state = {
currentExam: this.props.history.location.state.currentExam,
questions:this.props.history.location.state.currentExam.questions,
timeleft: this.props.history.location.state.currentExam.time,
selectedAnswers: [],
currentQuestionIndex: 0,
}
selectAnswer = (answerIndex) => {
let newSelectedAnswers = [...this.state.selectedAnswers];
newSelectedAnswers[this.state.currentQuestionIndex] = answerIndex;
this.setState((state, props) => ({
selectedAnswers: newSelectedAnswers,
timeleft: state.timeleft
}));
}
}
存储计时器的组件(位于父级的render()
中)
<ExamInfoBox currentQuestionNumber={this.state.currentQuestionIndex+1}
totalQuestionsAmount={this.state.questions.length}
time={this.state.timeleft}
>
</ExamInfoBox>
包含考试答案的组件
Answers = (props) => {
return (
<div className="exam-answers">
{
times(4, (i) => {
return (
<div className={classNames("exam-answer", this.isSelected(i+1) ? 'active' : '')}
key={i}
onClick={() => this.selectAnswer(i+1)}>
<span className='answer'>
{i}
</span>
</div>
)
})
}
</div>
)
}
包含考试答案的组件(在家长的render()
中)
<this.Answers question={props.question}/>
谢谢您的帮助!
答案 0 :(得分:0)
import React, { useState, useEffect} from 'react';
const Questions = ({ onStagePass,stageNum}) => {
return (
<div>
Stage Number {stageNum}
<button onClick={onStagePass}>
Next Stage
</button>
</div>
)
};
export const Exam = () => {
const [timeLeft, setTimeLeft] = useState(400);
const [stageNum, setStageNum] = useState(1);
useEffect( () => {
const timerInterval = setInterval(() => setTimeLeft(timeLeft => timeLeft -1),1000);
return () => clearInterval(timerInterval);
},[]);
return (
<div>
Time Left: {timeLeft}
<Questions onStagePass={() => setStageNum(stageNum+1)} stageNum={stageNum} />
</div>
)
};