There are two parts to that:
- Adding and removing the event listener
- Converting props to state on mount
1. Adding and removing the event listener
You're right to use useEffect, but useEffect doesn't pass any argument to its callback. To remove the listener, you return a cleanup function:
useEffect(() => {
const handler = handleClickOutside;
document.addEventListener("mousedown", handler);
return () => {
document.removeEventListener("mousedown", handler);
};
}, []);
Notice that we capture the function we set in handler so that we could be sure to remove the same function (in case handleClickOutside gets recreated, as function sometimes do in function components).
2. Converting props to state on mount
Don't. :-) Props are state that your parent component manages. Your component shouldn't copy props to state, 99.9% of the time it's an anti-pattern; instead, it should just use the props. If the component needs to be able to change the value of a prop, the parent component should pass it a function to do that. See the documentation for the class component getDerivedStateFromProps function for more about not doing this.
In your case, you were only copying the prop to state on mount, which means that updates to the prop after mount were not being used. In the very rare use case where you need to do that, the equivalent with hooks is to use the prop as the initial value with useState:
function Example({defaultText}) {
const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
// ...
}
And for completeness, for the very rare use case where you need to have a state property that's updated whenever a prop is updated, you'd use useEffect:
function Example({defaultText}) {
const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
// ...
useEffect(() => {
setDefaultSelectText(defaultText);
}, [defaultText]); // <== Dependency is the prop
// ...
}
...but note that that particular example is pointless; the state value just mirrors the prop. You'd have to be doing something with the value when making it state for that to make sense.