I have a HeaderIcon
component that looks like this:
function HeaderIcon({ inactiveIcon, activeIcon }) {
const [isActive, setIsActive] = useState(false);
return (
<div onClick={() => setIsActive(!isActive)}>
{isActive ? activeIcon : inactiveIcon}
</div>
);
}
export default HeaderIcon;
When I run my code I got these errors:
Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
And I checked my console and saw this:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
This is where I used my HeaderIcon
:
function Header() {
return (
<IconContext.Provider value={{ size: "30", color: "#374957" }}>
<header className="flex items-center justify-around py-1.5 px-3 bg-white">
<div className="flex items-center space-x-2 w-full max-w-xs">
<h1 className="text-4xl">Zipp</h1>
</div>
<div className="py-2.5 px-4 flex items-center">
<InputGroup>
<InputLeftElement
pointerEvents="none"
children={<SearchIcon color="grey" />}
/>
<Input
type="text"
bg="whitesmoke"
w={"full"}
focusBorderColor="none"
border={"none"}
placeholder="Search"
/>
</InputGroup>
</div>
{/* right */}
<div className="flex items-center space-x-6">
<div className="headerIcons active:opacity-80">
<Link href="/">
<HeaderIcon
inactiveIcon={<AiOutlineHome />}
activeIcon={<AiFillHome />}
/>
</Link>
</div>
<div className="headerIcons">
<HeaderIcon
inactiveIcon={<MdOutlineAddBox />}
activeIcon={<MdAddBox />}
/>
</div>
<div className="headerIcons -rotate-12">
<HeaderIcon
inactiveIcon={<AiOutlineNotification />}
activeIcon={<AiFillNotification />}
/>
</div>
<div className="cursor-pointer">
<Avatar w={7} h={7} />
</div>
</div>
</header>
</IconContext.Provider>
);
}
CodePudding user response:
Since you are adding a Functional Component inside Next.js's Link
tag, there are some changes to be made. Here is an overview of what the say in the documentation:
If the child of
Link
is a functional component, in addition to usingpassHref
, you must wrap the component inReact.forwardRef
.
Which means, first you should add passHref
prop to Link
when using HeaderIcon
, this way:
<Link href="/" passHref>
<HeaderIcon
inactiveIcon={<AiOutlineHome />}
activeIcon={<AiFillHome />}
/>
</Link>
Then change HeaderIcon
to the following code. Notice I'm using useRouter
from Next.js to handle active and inactive state.
import { useRouter } from "next/router";
const HeaderIcon = ({ onClick, href, inactiveIcon, activeIcon }, ref) => {
const router = useRouter();
return (
<a href={href} onClick={onClick} ref={ref}>
<div>{router.pathname ? activeIcon : inactiveIcon}</div>
</a>
);
};
export default React.forwardRef(HeaderIcon);
CodePudding user response:
function HeaderIcon(props) {
const [isActive, setIsActive] = useState(false);
const { inactiveIcon, activeIcon } = props;
return (
<div onClick={() => setIsActive(!isActive)}>
{isActive ? activeIcon : inactiveIcon}
</div>
);
}
export default HeaderIcon;
I hope this will be helpful for you. Thanks