I'm stuck trying to get the ui-fabric Nav component working with react-router-dom v4+. My solution "works", but the whole page is rerendered instead of just the NavSelection component. After some research i realize i need to do a e.preventDefault() somewhere, but i can't figure out where to add it.
Main Page:
export const Home = () => {
return (
<div className="ms-Grid-row">
<div className="ms-Grid-col ms-u-sm6 ms-u-md4 ms-u-lg2">
<Navbar />
</div>
<div className="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg10">
<NavSelection />
</div>
</div>
);
}
Navbar:
const navGroups = [
{
links: [
{ name: 'Name1', url: '/Name1', key: '#Name1' },
{ name: 'Name2', url: '/Name2', key: '#Name2' }
]
}
];
export class Navbar extends React.Component<any, any> {
constructor(props: INavProps) {
super(props);
this.state = {
selectedNavKey: '#Name1'
};
}
public componentDidMount() {
window.addEventListener('hashchange', (e) => {
this.setState({ selectedNavKey: document.location.hash || '#' });
});
}
public render(): JSX.Element {
const { selectedNavKey } = this.state;
return (
<Nav
selectedKey={selectedNavKey}
groups={navGroups}
/>
);
}
}
NavSelection:
export const NavSelection = () => {
return (
<div>
<Route path="/Name1" component={Component1} />
<Route path="/Name2" component={Component2} />
</div>
);
}
Any help is greatly appreciated
Edit: I've tried to put it inside componentDidMount like this:
public componentDidMount() {
window.addEventListener('hashchange', (e) => {
e.preventDefault();
this.setState({ selectedNavKey: document.location.hash || '#' });
});
}
That does not work.
Use the HashRouter instead of the BrowserRouter.
Example:
Router:
...
import { Switch, Route, Redirect, HashRouter } from 'react-router-dom'
...
export const Router: React.FunctionComponent = () => {
// persisted to localStorage
const navActiveItem = useSelector(selectNavActiveItem)
return (
<Suspense fallback={<LargeSpinner />}>
<HashRouter>
<Switch>
<Route exact path="/" render={() => (
<Redirect to={navActiveItem.url} />
)}/>
<Route exact path="/dashboard/overview" component={Overview} />
<Route exact path="/dashboard/progress" component={Progress} />
<Route exact path="/dashboard/issues" component={Issues} />
...
</Switch>
</HashRouter>
</Suspense>
)
}
Navigation:
...
const navLinkGroups: INavLinkGroup[] = [
{
name: 'Dashboard',
expandAriaLabel: 'Expand Dashboard section',
collapseAriaLabel: 'Collapse Dashboard section',
links: [
{
key: 'DashboardOverview',
name: 'Overview',
icon: 'BIDashboard',
url: '#/dashboard/overview',
},
{
key: 'DashboardProgress',
name: 'Progress',
icon: 'TimelineProgress',
url: '#/dashboard/progress',
},
{
key: 'DashboardIssues',
name: 'Issues',
icon: 'ShieldAlert',
url: '#/dashboard/issues',
},
],
},
...
export const Navigation: React.FunctionComponent = () => {
const navActiveItem = useSelector(selectNavActiveItem)
const dispatch = useDispatch()
const onLinkClick = (ev?: React.MouseEvent<HTMLElement>, item?: INavLink) => {
dispatch(setNavActiveItem(item || { name: '', url: '/' }))
}
return (
<Stack tokens={stackTokens} styles={stackStyles}>
<Nav
styles={navStyles}
ariaLabel="Navigation"
groups={navLinkGroups}
onLinkClick={onLinkClick}
initialSelectedKey={navActiveItem.key}
/>
</Stack>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With