React-Router路由组件在页面刷新时构造两次

时间:2017-08-22 17:46:32

标签: reactjs react-router

我有一个组件可以在与setInterval相关联的组件的componentDidMount中使用/testRoute启动计时器。

看起来像:

componentDidMount() {
        if (this.timer == null) {
            var timerFunction = function() { this.tick() }.bind(this)
            this.timer = setInterval(timerFunction, 500);   
        }
    }

我有一个代码平衡线,用于在组件“消失”时删除计时器(不确定此生命周期钩子在多大程度上等同于对象死亡,例如取消分配),

componentWillUnmount() {
        clearInterval(this.timer)
    }

问题在于,如果我在路线/testRoute并刷新浏览器,则constructor()会被调用两次,componentDidMount也是如此。此时,有两个“定时器”滴答作响。如果我导航到另一条路线,则会调用componentWillUnmount并清除其中一个计时器。但那还是留下了那个。

我的组件在页面刷新时应该按componentDidMount两次的预期行为吗?如果是这样,我怎样才能确保只设置一个计时器?

编辑:

- 使用骨架示例来证明这一点:

function Nav() {    
        return (
            <ul className='nav'>
            <li><Link to='/test'>test</Link></li>
            </ul>
            )

}

使用单一路线:

class App extends React.Component {

    render() {
        return (
            <Router>
            <div>
            <Nav />
            <Route path='/test' component={Test} />
            </div>
            </Router>
            )
    }
}

一个微不足道的组成部分:

class Test extends React.Component {
    constructor() {
        super()
        console.log("constructor")
    }
    render() {
        return <div>test</div>
    }
}

在此代码中:“构造函数”在刷新/test时两次登录到控制台。

1 个答案:

答案 0 :(得分:0)

我有类似的问题,我的组件安装了两次。就我而言,我在componentDidMount中发出了一个请求,该请求被调用了两次。我通过异步调用(App.ROUTES)从服务器获取一些Route,而将某些作为静态(routeInfo.insideDashboard)。静态组件将安装两次。

<Dashboard specialMenu={this.state.menu}>
    <Switch>
        {routeInfo.insideDashboard.map(route =>
            <Route exact key={route.path} path={route.path} component={Auth(route.component)}/>)}
        {App.ROUTES.map(route => <Route key={route.urlPath} exact path={"/" + route.urlPath} 
            component={Auth(asyncComponent(route.importPath, {title: route.title}))}/>)} 
        <Route component={NotFound}/>
     </Switch>
</Dashboard>

我怀疑原因可能是静态路由(routeInfo.insideDashboard)渲染两次,其他路由来自服务器之前和之后。我在渲染Routes之前添加了一个检查routesFromServerTaken,以确保Route(定义)仅渲染一次。

<Dashboard specialMenu={this.state.menu}>
    <Switch>
        {routesFromServerTaken ? routeInfo.insideDashboard.map(route =>
            <Route exact key={route.path} path={route.path} component={Auth(route.component)}/>): null}
        {App.ROUTES.map(route => <Route key={route.urlPath} exact path={"/" + route.urlPath} 
            component={Auth(asyncComponent(route.importPath, {title: route.title}))}/>)} 
        <Route component={NotFound}/>
     </Switch>
</Dashboard>

这解决了我的问题,组件现在只能安装一次。