Reputation: 345
I am making a navbar, using NavLink from React-Router-Dom. Using 'isActive' prop to style the active Link, is okay. But, how could I style the subelements inside of it. To be exact, please see this ...
const Nav = [
{path : '/', icon : <NavIcon.Home />},
{path : '/service', icon : <NavIcon.Service />}
]
function someFunc(){
return (
Nav.map(({path, icon}) => (
<NavLink key={path} to ={path}>
{icon} //this icon is actually an svg icon and i want to change its 'fill' attr. conditionally, when the navLink is active or not. I am using .ts
</NavLink>
))}
}
const Home = () => {
<svg ....other attributes .... fill ={isActive ? 'color1' : 'color2'}> //I want this fill to be conditional so based on as to link is active or not. (**this svg exists into different component, as so do the NavLink**).
...
</svg>
}
how should I use 'isActive' from navLink inside of my svg component? and connect to 'isActive' inside of inside of entirely different component?
ps : - I TRIED making interface type in svg component as
interface Props extends NavLinkProps {
isActive : boolean;
}
const Home = ({isActive} : Props) => {
return (
<svg fill ={isActive ? 'color1' : 'color2'}>
...
</svg>
)
}
and then tried using this into my Nav.tsx component
const Nav = [
{path : '/', icon : <NavIcon.Home isActive = {'what should I put here?'} />},
{path : '/service', icon : <NavIcon.Service isActive = {} />}
]
return (
<NavLink to ={path} key ={path} className = {({isActive}) => isActive ? 'class1' : 'class2'}>
{icon}
</NavLink>
)
"My main aim is to change the 'fill color' of the svg wrapped around NavLink , based on whether the NavLink is active or not"
Upvotes: 0
Views: 902
Reputation: 202608
In addition to the NavLink
component taking a function prop on the className
and style
props, the children
prop can also take a function and is passed the isActive
property.
declare function NavLink( props: NavLinkProps ): React.ReactElement; interface NavLinkProps extends Omit< LinkProps, "className" | "style" | "children" > { caseSensitive?: boolean; children?: | React.ReactNode | ((props: { isActive: boolean }) => React.ReactNode); className?: | string | ((props: { isActive: boolean; }) => string | undefined); end?: boolean; style?: | React.CSSProperties | ((props: { isActive: boolean; }) => React.CSSProperties); }
Reconfigure the Nav
array to instead hold a reference to the icon component you want to render and pass extraneous props to at runtime.
const nav = [
{ path: '/', end: true, icon: NavIcon.Home }, // only match when exactly "/"
{ path: '/service', icon: NavIcon.Service }
];
When mapping the nav
array use the children
function prop and pass the isActive
property as a prop to the icon component.
nav.map(({ icon: Icon, ...props }) => (
<NavLink key={props.path} {...props}>
{({ isActive }) => <Icon isActive={isActive} />}
</NavLink>
))}
Upvotes: 1