function NavigationLink({ to, title, exactPath, Icon }) {
const resolved = useResolvedPath(to);
const match = useMatch({
path: resolved.pathname,
end: exactPath,
});
const [active, setActive] = useState(false);
return (
<StyledNavLink linkSelected={match}>
<NavLink
to={to}
style={({ isActive }) =>
isActive ? setActive(true) : setActive(false)
}
>
<Title>{title}</Title>
<SelectedContainerIcon active={active}>
<Icon />
</SelectedContainerIcon>
</NavLink>
</StyledNavLink>
);
}
Right now I am using this, using the "isActive" to change a state that is then passed to the child component (to change the icon's background color) but it is giving me a rendering error (despite actually working well). Is there a way to pass the "isActive" directly to the child?
In addition to taking a function callback for the className
and style
prop, the NavLink
also takes a render function as the children
prop.
Don't use the className
or style
props to issue side-effects like enqueueing state updates.
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); }
Your code:
function NavigationLink({ to, title, exactPath, Icon }) {
const resolved = useResolvedPath(to);
const match = useMatch({
path: resolved.pathname,
end: exactPath,
});
return (
<StyledNavLink linkSelected={match}>
<NavLink to={to}>
{({ isActive }) => (
<>
<Title>{title}</Title>
<SelectedContainerIcon active={isActive}>
<Icon />
</SelectedContainerIcon>
</>
)}
</NavLink>
</StyledNavLink>
);
}
Dynamically render a className
based on the isActive
property, instead of the style
attribute, and use CSS descendent selectors to change children of the active class.
<NavLink
to={to}
className={({ isActive }) => isActive ? "active" : "" }
>
<Title>{title}</Title>
<SelectedContainerIcon>
<Icon />
</SelectedContainerIcon>
</NavLink>
.active i {
background-color: blue
}
With this solution it probably won't be necessary to save the active
status to state. CSS will do the logic for you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.