palantir/blueprint
在 GitHub 查看Selected Tab indicator is sometimes misaligned on page load/refresh when using React Router.
Open
#3,824 建立於 2019年11月7日
P3Package: coreType: bughelp wanted
描述
Environment
@blueprintjs/core 3.17.1
The problem manifests in many browser/OS combinations.
Steps to reproduce
- Use Tabs with Router in such a way that the route determines which tab is selected.
- Refresh a URL that causes a tab to be selected.
import React, { PureComponent } from 'react';
import { withRouter } from 'react-router-dom';
import { HeaderTabs, getTabId } from './our/code';
class Header extends PureComponent {
render() {
/* Selected tab ID is derived from the Router-supplied 'history' object */
const tabId = getTabId( this.props.history.location.pathname );
return (
<div>
<HeaderTabs tabId={tabId} />
</div>
);
}
}
export default withRouter(Header);
import React, { PureComponent } from 'react';
import { Tab, Tabs } from '@blueprintjs/core';
export default class HeaderTabs extends PureComponent {
componentDidMount() {
/* Hack to compensate for selected tab indicator being misaligned on refresh. */
setTimeout( () => this.forceUpdate(), 1000 );
}
render() {
return (
<div>
<Tabs selectedTabId={ this.props.tabId } >
{ [ _array of valid tab data objects_ ].map(tabProps => (<Tab {...tabProps}/>)) }
</Tabs>
</div>
);
}
}
Actual behavior
Sometimes when the component mounts, the indicator for the selected tab will be misplaced and/or mis-sized. The degree of mis-sizing is inconsistent, and it does not always occur. (Example of misplacement below.)
This occurs only when the component mounts. Once mounted, selecting any tab will cause the indicator to position/size correctly.
We are using animated indicator.
Expected behavior
Tab indicator should always have correct size and placement.
Possible solution
This hack ameliorates the issue. Whatever component is rendering the <Tabs> is forced to update after the HTML has rendered, which causes the indicator to size correctly. (This is the same effect as clicking a tab.)
class SomethingThatUsesTabs extends PureComponent {
componentDidMount() {
setTimeout(() => this.forceUpdate(), 1000);
}
render() {
return <Tabs ... > ... </Tabs>
}
}