如何使用state将样式添加到sidenav中的活动选项卡



我正在制作一个侧导航,我需要将左边框添加到当前选项卡。如何通过将布尔值作为道具传递给Child SideNavItem类并在每次选项卡更改时对其进行更改来使用状态来实现这一点。

这是我为父SideNav类编写的代码这里我使用if-else条件来检查当前位置和作为子类道具的通行证。但现在,主页和我的个人资料都处于边缘。

import { NavLink } from "react-router-dom";
import SideNavItems from "./SideNavItems";
import React, {useState} from 'react';

const HomeIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
/>
</svg>
);
const ProfileIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
);
const PointIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
/>
</svg>
);
const SupportIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
/>
</svg>
);
const ContributeIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
/>
</svg>
);


const SideNav = (): JSX.Element => {
let [active, setActive] = useState(true);
let isActive = (currentPath: any, thisPath: any) => {
if (currentPath===thisPath) {
setActive(true)
} else {
setActive(false);
}
return active;
}
const resetState = () => {
setActive(false);
};
return (
<div className="sidebar mt-5">
<div className="logo ml-2">
<img
alt="logo"
src={require("../assets/images/logo.png").default}
/>
</div>
<NavLink to="/"><SideNavItems active={() => isActive(window.location.pathname, "/")} icon={HomeIcon} text={"Home"}/></NavLink>
<NavLink to="/profile"><SideNavItems active={() => isActive(window.location.pathname, "/profile")} icon={ProfileIcon} text={"My Profile"}/></NavLink>
<SideNavItems active={""} icon={PointIcon} text={"Daily Points"}/>
<SideNavItems active={""} icon={SupportIcon} text={"Support"}/>
<SideNavItems active={""} icon={ContributeIcon} text={"Contribute"}/>
</div>
);
};
export default SideNav;

这是子类的代码

import React from "react";
type Props = {
active: any;
text: string;
icon: any;
};
const SideNavItems: React.FC<Props> = ({active, icon, text }) => (
<div className={`flex items-center cursor-pointer hover:text-red-400 transition duration-100 ease-in-out ${active ? ` text-red-400 border-l-4 border-red-400` : ``}`}>
<div className="icon p-5">{icon}</div>
<h2 className="font-extrabold text-xl mr-5">{text}</h2>
</div>
);
export default SideNavItems;

您在这里面临的部分困惑是由于在isActive函数中调用setActive不会立即更改active变量的值,而且由于您立即返回active变量,因此实际上返回的是以前的值active,而不是预期值。

事实上,您可能不需要将active的值保存在组件状态变量中:

const SideNav = (): JSX.Element => {
return (
<div className='sidebar mt-5'>
<div className='logo ml-2'>
<img alt='logo' src={require('../assets/images/logo.png').default} />
</div>
<NavLink to='/'>
<SideNavItems
active={window.location.pathname === '/'}
icon={HomeIcon}
text={'Home'}
/>
</NavLink>
<NavLink to='/profile'>
<SideNavItems
active={window.location.pathname === '/profile'}
icon={ProfileIcon}
text={'My Profile'}
/>
</NavLink>
<SideNavItems active={''} icon={PointIcon} text={'Daily Points'} />
<SideNavItems active={''} icon={SupportIcon} text={'Support'} />
<SideNavItems active={''} icon={ContributeIcon} text={'Contribute'} />
</div>
);
};
export default SideNav;

或者,如果您使用的是react路由器,您可以使用useLocation挂钩来确保组件在路径更改时始终重新渲染:

import { useLocation } from 'react-router-dom';
const SideNav = (): JSX.Element => {
const { pathname: currentPath } = useLocation();
return (
<div className='sidebar mt-5'>
<div className='logo ml-2'>
<img alt='logo' src={require('../assets/images/logo.png').default} />
</div>
<NavLink to='/'>
<SideNavItems
active={currentPath === '/'}
icon={HomeIcon}
text={'Home'}
/>
</NavLink>
<NavLink to='/profile'>
<SideNavItems
active={currentPath === '/profile'}
icon={ProfileIcon}
text={'My Profile'}
/>
</NavLink>
<SideNavItems active={''} icon={PointIcon} text={'Daily Points'} />
<SideNavItems active={''} icon={SupportIcon} text={'Support'} />
<SideNavItems active={''} icon={ContributeIcon} text={'Contribute'} />
</div>
);
};
export default SideNav;

最新更新