【发布时间】:2020-08-18 15:58:36
【问题描述】:
我正在使用 React 钩子创建一个计时器。这是一个用于测验的简单组件。每个问题都有一个定义的持续时间,因此计时器应该从这个持续时间开始,并开始减少一秒。我的问题是组件做了应该做的事情,但是当我进入下一个问题时,状态不会初始化为道具中传递的持续时间,而是继续使用计数器......
const Timer = ({ duration }) => {
const [counter, setCounter] = useState(duration);
const timer = useRef();
debugger;
console.log("counter: " + counter);
const setTimer = () => {
if (counter <= duration) {
setCounter(counter - 1);
}
};
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
timer.current = setTimeout(() => setTimer(), 1000);
return () => {
if (timer.current) {
console.log("ClearInterval in Timer");
clearTimeout(timer.current);
}
};
}, [counter]);
return (
<div>
<p>time left {counter} seconds</p>
</div>
);
};
export default Timer;
我正在从 Card 组件渲染 Timer 组件:
import React from "react";
import QuizButton from "../QuizButton/QuizButton";
import Timer from "../Timer/Timer";
import "./styles.css";
const QuizQuestion = ({ question, responses, checkAnswerFn, duration }) => (
<article className='card'>
<header>
<Timer duration={duration} />
</header>
<div>
<p>{question}</p>
</div>
<footer>
{responses.map((response, i) => {
return (
<QuizButton key={i} onClick={checkAnswerFn(response)}>
{response}
</QuizButton>
);
})}
</footer>
</article>
);
export default QuizQuestion;
有谁知道为什么在问题重新呈现后状态没有初始化为持续时间?
【问题讨论】:
-
State 不应该为后续渲染重新初始化,这就是重点。你的意思是组件
Timer应该重新挂载吗? -
不,我希望下次渲染Timer,因为渲染了下一个Question,持续时间从props中传递的值开始
-
我真的不认为你这样做......如果每次
Timer呈现时counter都重置为duration,它永远不会减少。调用setCounter会触发Timer的重新渲染。 -
如果你不想让它重新挂载,而只是在
duration改变时重置counter,那么也许你可以设置一个useEffect在duration属性改变时运行?但是,如果duration值没有改变每个问题,那么这也不起作用。 -
谢谢布赖恩,你是对的,我每次使用 setCounter 时都会重新渲染组件。我以为一旦我用不同的 props 值再次重新渲染 Timer,那么 useState 会将状态重新初始化为 props 中传递的值......但我想我并不完全了解组件的生命周期......跨度>
标签: reactjs react-hooks