One of the things that you end up developing in one point or in the other is a breadcrumbs navigation system. I’ve seen some posts across the web touting how to achieve it in React and Reach Router by providing complex looping mechanisms. In this post, I show you a simpler, non loop way that displays breadcrumbs in Reach-Router.
I’ll be using CSS-In-JS (Not required), React 16.13 (could be lower), TypeScript, and Reach-Router 1.3.x. No hooks are needed, but components are functional.
Here’s all the code that you’ll need.
type BreadrumbsProps = {
url: string;
text: string;
className?: string;
};
// This is material-ui. You can use any CSS-In-JS approach.
const useStyles = makeStyles(() => ({
root: {
display: 'block',
},
right: {
float: 'right',
},
left: {
float: 'left',
},
clear: {
clear: 'both',
},
separator: {
padding: '6px',
},
}));
export const AppBreadcrumbs: React.FC<RouteComponentProps> = memo((props) => {
const styles = useStyles();
return (
<>
<Router primary={false}>
<Bread path="/" url={'/'} text={'Home'} className={styles.left}>
<Bread
path={"/evaluation"}
url={"/evaluation"}
text={'Evaluation'}
>
<Bread
path="instruments"
url={'/evaluation/instruments'}
text={'Instruments'}
>
<Bread
path=":classId/:period/:instrument/*"
url={'../'}
text={'Period'}
></Bread>
</Bread>
<Bread
path="indicators"
url={'/evaluation/indicators'}
text={'Indicators'}
></Bread>
</Bread>
<Bread
path={"/planning" + '/*'}
url={"/planning"}
text={'Indicators'}
></Bread>
<Bread
path={"/attendance" + '/*'}
url={"/attendance"}
text={'Asistencia'}
></Bread>
<Bread
path={"/scores" + '/*'}
url={"/scores"}
text={'Calificaciones'}
></Bread>
<Bread
path={"/content" + '/*'}
url={"/content"}
text={'Contenido de Clases'}
></Bread>
</Bread>
</Router>
<div className={styles.clear} />
</>
);
});
export default AppBreadcrumbs;
const Bread: React.FC<RouteComponentProps & BreadrumbsProps> = memo((props) => {
const styles = useStyles();
const shouldRenderCrumb = !props.location?.pathname.endsWith(
props.path || '',
);
return (
<div className={props.className}>
<LinkButton size="small" variant="text" to={props.url}>
{props.text}
</LinkButton>
{shouldRenderCrumb && React.Children.count(props.children) > 0 && (
<div className={cls(styles.right)}>
<div className={cls(styles.left, styles.separator)}>{'>'}</div>
<div className={styles.left}>{props.children}</div>
</div>
)}
</div>
);
});
#react #react-router #javascript #single-page-web-applications #ux #ui #tutorial #web-development