The react version I'm using is:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Here's some simple code for the dropdown.
import { MouseEvent, useEffect, useState } from 'react';
import type { ReactNode } from 'react';
type DropdownProps = {
target: HTMLElement | null;
children: ReactNode;
};
function Dropdown({ target, children }: DropdownProps) {
useEffect(() => {
if (!target) return;
const listener = () => {
console.log('listener executed');
};
document.addEventListener('click', listener);
return () => document.removeEventListener('click', listener);
}, [target]);
if (!target) {
return null;
}
return <div>{children}</div>;
}
function App() {
const [target, setTarget] = useState<HTMLButtonElement | null>(null);
return (
<div>
<button
onClick={(e: MouseEvent<HTMLButtonElement>) =>
setTarget(e.currentTarget)
}
>
Button
</button>
<Dropdown target={target}>dropdown test</Dropdown>
</div>
);
}
export default App;
Here, when the button is pressed for the first time, an event is attached to the document and the listener is executed immediately.
The result of the first button press
The behavior I expect is that the first time the button is pressed, the event is attached to the document, and the next time the button is pressed, the listener fires.
In practice, however, the event listener fires as soon as the button is first pressed.
This was a problem that did not occur when using ReactDom.render
of React 17, but a problem occurs while using createRoot
of 18.
It seems to be a similar issue to the one in the link below
Popup using useState stopped working in React 18
I want to know why this doesn't work in react 18.