简体   繁体   English

仅在一个组件中调用方法

[英]Calling a method only in one component

I have a timer on my web app on the home component, that is doing some countdown. 我在家庭组件的Web应用程序上有一个计时器,该计时器正在倒计时。 Here's the Home component: 这是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>
        )
    }
}

Here's my Questions component: 这是我的Questions组件:

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

This is my App.js component: 这是我的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>
        );
    }
}

And just in case it matters this is my Navigation component: 以防万一,这是我的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>
        )
    }
}

What the problem is: When I open home component, all goes well, the timer fires up, and it's all pretty. 问题是什么:当我打开home组件时,一切运行良好,计时器启动,而且很漂亮。 But if I go to questions component, the timer() method is still trying to run, even though I didn't call it anywhere in the Assignments component. 但是,如果我去问题组件,即使没有在“工作Assignments组件的任何地方调用它, timer()方法仍在尝试运行。 That's when the app crashes. 那是应用崩溃的时候。

Adding a try catch block inside the timer() method like this: 在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) {

}

Solves the issue, but I'm pretty sure it's a bad practice. 解决了这个问题,但是我很确定这是一个不好的做法。

So how can I make it only be called when the Home component is being rendered? 那么如何使它仅在渲染Home组件时被调用?

You should remove the timer when the component unmounts. 卸载组件时,应删除计时器。 You can do this in the Home component's componentWillUnmount() life cycle method. 您可以在Home组件的componentWillUnmount()生命周期方法中执行此操作。

See: 看到:

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

Stop setInterval call in JavaScript 停止JavaScript中的setInterval调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM