[英]Connected React component unnecessarily re-renders when parent re-renders
[英](React)Child component pause its useEffect when the parent re-renders
編輯:這個問題已經通過在 useEffect Hooks 中添加第二個參數來解決。
我是反應新手,正在構建一個玩具反應游戲。 我借用了我在這里找到的這個計時器。 如果用戶執行操作並且父組件重新渲染,則計時器會在短時間內停止倒計時。 根據( https://reactjs.org/docs/hooks-effect.html ),react 會記住 useEffect function 之后在執行 DOM 更新后調用它, 如果這是原因,是否有任何解決方案或替代方案? 如果沒有,誰能指出我正確的方向? 任何幫助將不勝感激!
這是我的代碼片段供參考:
class Chalkboard extends Component {
constructor(props) {
super(props);
this.state = {
minutes: 1,
seconds: 0,
addSeconds: 0,
};
}
updateTimer() {
this.setState({ addSeconds: 0 });
}
handleTimer() {
window.removeEventListener('keydown', this.keyHandling);
this.setState({
gameOver: true,
});
}
render() {
return(
<Timer
initialMinutes={this.state.minutes}
initialSeconds={this.state.seconds}
onTimer={this.handleTimer}
addSeconds={this.state.addSeconds}
updateTimer={this.updateTimer}
/>
)
}
import React, { useState, useEffect } from 'react';
const Timer = (props) => {
const { initialMinutes = 0, initialSeconds = 0 } = props;
const [minutes, setMinutes] = useState(initialMinutes);
const [seconds, setSeconds] = useState(initialSeconds);
useEffect(() => {
let myInterval = setInterval(() => {
if (seconds > 0) {
setSeconds(seconds - 1);
}
else if (seconds === 0) {
if (minutes === 0) {
clearInterval(myInterval);
} else {
setSeconds(59);
setMinutes(minutes - 1);
}
}
}, 1000);
return () => {
clearInterval(myInterval);
};
});
useEffect(() =>{
if(props.addSeconds>0){
setSeconds(seconds + props.addSeconds);
props.updateTimer()
}
if(minutes === 0 && seconds === 0){
props.onTimer()
}
});
return (
<div className = "timer-container" >
{minutes === 0 && seconds === 0 ? null: (
<div>
{' '}
{minutes}:{seconds < 10 ? `0${seconds}` : seconds}
</div>
)}
</div>
);
};
export default Timer;
您能否提供有關https://codesandbox.io/的示例?
嘗試將[props, minutes, seconds]
作為第二個參數傳遞給 useEffect 掛鈎。 https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.