反应路由器:忽略hashchange
问题描述:
我有一个音频播放器,我希望当前URL始终指向当前播放的位置。所以我想我会用相同的密钥将新位置推送到路由器,告诉反应路由器它应该忽略散列更改。反应路由器:忽略hashchange
audioElement.addEventListener('timeupdate', (evt) => {
this.props.router.push({
...this.props.location,
hash: '#'+audioElement.currentTime
});
});
但是,随着音频回放,页面内容不断重新加载。我该如何防止路由器对hashchange事件做出反应?
我正在使用react router 3和redux。如果它做出改变,我愿意升级到v4版本,但它只是为了尝试而看起来太费劲了。
答
您最好将'#'+audioElement.currentTime
置于历史状态,因为更改散列总是会导致刷新(据我所知)。
audioElement.addEventListener('timeupdate', (evt) => {
this.props.router.push({
...this.props.location,
state: {
...this.props.location.state,
audioCurrentTime: '#'+audioElement.currentTime
}
});
});
答
我通过修补react-router/lib/createTransitionManager.js
得到它:
你可以像这样做。 有一个function listen
,我增加了大约这样的:
if (state.location.path === location.path && state.location.hash !== location.hash) {
/* do nothing */
}
else {
...
}
UPDATE:对于反应路由器4,你不用修补代码,只猴子修补路由器:
import { Router } from 'react-router-dom';
let previousLocation;
const routerSetState = Router.prototype.setState;
Router.prototype.setState = function(...args) {
const loc = this.props.history.location;
if (loc.pathname === previousLocation.pathname &&
loc.search === previousLocation.search &&
loc.hash !== previousLocation.hash
) {
previousLocation = {...loc};
return;
}
previousLocation = {...loc};
return routerSetState.apply(this, args);
};
const routerDidMount = Router.prototype.componentDidMount;
Router.prototype.componentDidMount = function(...args) {
previousLocation = {
...this.props.history.location,
};
if (typeof routerDidMount === 'function') {
return routerDidMount.apply(this, args);
}
};
谢谢@炼狱。存在的问题是,当我进行推送时,URL变为'''''',页面中断。但它不刷新,所以我认为我们正在走上正轨。 :-) – Sixtease
@Sixtease我编辑了答案,加了'... this.props.location' – Purgatory
我应该早点看过这个:这不能完成这项工作,因为它不会更改地址栏中的URL,所以复制粘贴URL的目的将指向当前位置,这不能通过这个来完成...除非我错了。 :-) 我也试过应用路由器中间件,但似乎不可能从那里取消重新渲染,真的。 :-( – Sixtease