仅在一个组件中调用方法

时间:2018-06-20 08:23:55

标签: javascript reactjs

我在家庭组件的Web应用程序上有一个计时器,该计时器正在倒计时。这是Home组件:

export default class Home extends React.Component {

    timer() {
        var countDownDate = new Date("Sep 5, 2018 15:37:25").getTime();
        var x = setInterval(() => {

            var now = new Date().getTime();

            var distance = countDownDate - now;

            var days = Math.floor(distance / (1000 * 60 * 60 * 24));
            var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            var seconds = Math.floor((distance % (1000 * 60)) / 1000);

            document.getElementById("timer").innerHTML = days + "d " + hours + "h "
                + minutes + "m " + seconds + "s ";

            if (distance < 0) {
                clearInterval(x);
                document.getElementById("timer").innerHTML = "EXPIRED";
            }
        }, 1000);
    }

    componentDidMount() {
        $('.monster').fadeIn('slow');
        this.timer();
    }


    render() {
        return (
            <div id="timer"></div>
        )
    }
}

这是我的Questions组件:

export default class AssignmentsComponent extends React.Component {
    render() {
        return (
            <h1>Questions Component</h1>
        )
    }
}

这是我的App.js组件:

export default class App extends Component {
    render() {
        return (
            <div className="App">
                <NavigationComponent {...this}/>
                {/*<CheckIfHasCurrentTasksComponent user={firebase.auth().currentUser}/>*/}
                {/*{this.state.user ? <Questions/> : <Home/>}*/}
            </div>
        );
    }
}

以防万一,这是我的Navigation组件:

export default class NavigationComponent extends React.Component {

    render() {
        return (
            <BrowserRouter>
                <React.Fragment>
                    <Navbar className="fixedTop custom_navbar half_transparent">
                        <Nav className="float_right">
                            <NavItem className="custom_button_navbar"><span>pobierz</span></NavItem>

                            {
                                firebase.auth().currentUser !== null ?
                                    <React.Fragment>
                                        <LinkContainer id="assignments" to='/assignments'>
                                            <NavItem>Zadania</NavItem>
                                        </LinkContainer>
                                        <NavItem onClick={logout.bind(this)}>Wyloguj się</NavItem>
                                    </React.Fragment>
                                    :
                                    <NavItem onClick={this.openLogin}
                                             className="custom_button_navbar"><span>Zaloguj się</span></NavItem>
                            }

                        </Nav>
                    </Navbar>
                    <Switch>
                        <Route exact path="/assignments" render={
                            () => (firebase.auth().currentUser === null ?
                                <Redirect to='/'/> : <AssignmentsComponent/>)
                        }/>

                        <Route exact path='/assignment/:id' render={
                            props => (
                                firebase.auth().currentUser === null ?
                                    <Redirect to='/'/> : <CheckIfHasCurrentTasksComponent {...props}/>
                            )
                        }/>

                        <Route exact path="/" component={HomeComponent}/>
                    </Switch>
                    <LoginFormComponent show={this.state.show} changeShowState={this.changeShowState}/>
                </React.Fragment>
            </BrowserRouter>
        )
    }
}

问题是什么:当我打开home组件时,一切顺利,计时器启动,而且一切都很好。但是,如果我去问题组件,即使我没有在timer()组件中的任何地方调用它,Assignments方法仍在尝试运行。那是应用程序崩溃的时候。

在timer()方法内添加一个try catch块,如下所示:

try {
    document.getElementById("timer").innerHTML = days + "d " + hours + "h "
        + minutes + "m " + seconds + "s ";

    if (distance < 0) {
        clearInterval(x);
        document.getElementById("timer").innerHTML = "EXPIRED";
    }
} catch (e) {

}

解决了这个问题,但是我很确定这是一个不好的做法。

那么如何使它仅在呈现Home组件时被调用?

1 个答案:

答案 0 :(得分:2)

在卸载组件时,应删除计时器。您可以在Home组件的componentWillUnmount()生命周期方法中执行此操作。

请参阅:

https://reactjs.org/docs/react-component.html#componentwillunmount

Stop setInterval call in JavaScript