在Next Js中单击外部时隐藏下拉菜单



刚开始学习Next Js。我想在点击按钮外部时隐藏下拉列表。代码在create-react-app中工作得很好。但是我试图在nextjs中实现,它不起作用。

const LanguageRef = useRef();
const [languageDD, setLanguageDD] = useState(false);
console.log(languageDD);
useEffect(() => {
if (!languageDD) return;
const checkIfClickedOutside = (e) => {
if (
languageDD &&
LanguageRef.current &&
!LanguageRef.current.contains(e.target)
) {
setLanguageDD(false);
}
};
document.addEventListener("click", checkIfClickedOutside);
return () => {
// Cleanup the event listener
document.removeEventListener("click", checkIfClickedOutside);
};
}, [languageDD]);

链接标签

<a onClick={() => setLanguageDD((prev) => !prev)}>Language </a>

useEffect在Nextjs中工作吗?

工作解决方案:

const LanguageRef = useRef();
const LanguageDDRef = useRef();
const [languageDD, setLanguageDD] = useState(false);
console.log(languageDD);
useEffect(() => {
console.log("useeffect")
if (!languageDD) return;
const checkIfClickedOutside = (e) => {
if (
languageDD &&
LanguageRef.current &&
!LanguageRef.current.contains(e.target)  &&
LanguageDDRef.current &&
!LanguageDDRef.current.contains(e.target)
) {
setLanguageDD(false);
}
};
document.addEventListener("click", checkIfClickedOutside);
return () => {
// Cleanup the event listener
document.removeEventListener("click", checkIfClickedOutside);
};
}, [languageDD]);
<a onClick={() => setLanguageDD((prev) => !prev) ref={LanguageDDRef}}>Language </a>

我重新设计并将clickOutside函数拆分为Custom Hook,因为它可以在其他组件上重用。这样的:

import React, { useEffect } from 'react';
export const useClickOutside = (ref, handler) => {
useEffect(() => {
const listener = (e) => {
// Do nothing if clicking ref's element or descendent elements
if (!ref?.current || ref.current.contains(e.target)) {
return;
}
handler();
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
document.removeEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
};
}, [handler, ref]);
};

最后,你只需要import和使用useClickOutside挂钩,像这样:

import React, { useRef, useState } from 'react';
import { useClickOutside } from '../src/hooks';
export default function Home() {
const LanguageDDRef = useRef();
const [languageDD, setLanguageDD] = useState(true);
useClickOutside(LanguageDDRef, () => setLanguageDD(false));
const handleToggleButton = () => {
setLanguageDD((prev) => !prev);
};
return (
<button onClick={handleToggleButton} ref={LanguageDDRef}>
{languageDD ? 'Show' : 'Hide'}
</button>
);
}

最新更新