(React) 子组件在父组件重新渲染时暂停其 useEffect

时间:2021-03-30 07:26:12

标签: javascript html reactjs react-hooks react-functional-component

编辑:此问题已通过在 useEffect Hooks 中添加第二个参数解决。

我是 React 新手,正在构建一个玩具 React 游戏。我借用了我找到的这个计时器 here。如果用户执行一个操作并且父组件重新渲染,计时器会停止倒计时一小段时间。根据 (https://reactjs.org/docs/hooks-effect.html),react 会记住 useEffect 函数,并在执行 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;

1 个答案:

答案 0 :(得分:0)

您能否提供有关 https://codesandbox.io/ 的示例?

尝试将 [props, minutes, seconds] 作为 useEffect 钩子中的第二个参数传递。 https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect