I have the code below. The problem is, like the documentation says, if you use an useEffect with an empty array of dependencies, you're stuck with the initial values of the states or variables. What can I do to solve the if in line 7
const UserNotification = ({ notificationData, unreadNotifications, setUnreadNotifications }) => {
const [isOpenNotification, setIsOpenNotification] = useState(false);
const handleClickOutside = (e) => {
const parent = document.querySelector('[data-notification]');
if (!parent.contains(e.target)) {
if (isOpenNotification && unreadNotifications) {
setUnreadNotifications((s) => false);
}
setIsOpenNotification((s) => false);
}
};
const handleClickReadAll = () => {
setUnreadNotifications((s) => false);
};
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
return (
<div
data-notification
>
<div className="relative">
<ClassicButton
type="custom"
onClick={() => setIsOpenNotification((s) => !s)}
className="text-custom-gray-3 rounded-full"
icon={<Icon path={mdiBell} size={1.2} color={theme.colors['custom-gray-2']} />}
/>
{ unreadNotifications && (
<div className="absolute border-0 rounded-full w-[7px] h-[7px] bg-red-600 bottom-0 right-0" />
) }
</div>
{isOpenNotification && (
<NotificationList
data={notificationData}
handleClickReadAll={handleClickReadAll}
/>
)}
</div>
);
};
export default UserNotification;
CodePudding user response:
You update the useEffect
when required
const handleClickOutside = useCallback((e) => {
const parent = document.querySelector('[data-notification]');
if (!parent.contains(e.target)) {
if (isOpenNotification && unreadNotifications) {
setUnreadNotifications(false);
}
setIsOpenNotification(false);
}
}, [isOpenNotification, unreadNotifications]);
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [handleClickOutside]);
CodePudding user response:
Use a ref (openAndUnread
) to hold the boolean value of isOpenNotification && unreadNotifications
, and update it in another useEffect
block.
const UserNotification = ({ notificationData, unreadNotifications, setUnreadNotifications }) => {
const [isOpenNotification, setIsOpenNotification] = useState(false);
const openAndUnread = useRef(false);
const handleClickReadAll = () => {
setUnreadNotifications(false);
};
useEffect(() => {
openAndUnread.current = isOpenNotification && unreadNotifications;
});
useEffect(() => {
const handleClickOutside = (e) => {
const parent = document.querySelector('[data-notification]');
if (!parent.contains(e.target)) {
if (openAndUnread.current) {
setUnreadNotifications(false);
}
setIsOpenNotification(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);