我有一个组件可以在与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
时两次登录到控制台。
答案 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>
这解决了我的问题,组件现在只能安装一次。