Issue
I am trying to create a typescript/react modal component that closes when the close button is clicked and when the area off the modal body is clicked. I've tried a bunch of solutions but I can't get the compiler types correct. I think the issue is my event type. I've tried Event, SyntheticEvent, MouseEvent, React.MouseEvent and a couple others. I just can't get the behavior I want with no compiler errors. Any help is appreciated.
here is a link to a codesandbox of my issue the example is set up to show all the compiler error messages.
interface State {
isOpen: boolean;
}
class Modal extends React.Component {
public state: State = { isOpen: true };
public wrapperRef: React.RefObject<HTMLDivElement> = React.createRef();
public componentWillMount(): void {
document.addEventListener("click", this.documentClickHandler);
}
public componentWillUnmount(): void {
document.removeEventListener("click", this.documentClickHandler);
}
public documentClickHandler = (event: EventListener): void => {
console.log("doc click", event);
console.log("ref", this.wrapperRef);
};
public closeModal = (): void => {
this.setState({ isOpen: false });
};
public render(): JSX.Element | null {
const { isOpen } = this.state;
return !isOpen ? null : (
<div
className="modal_wrapper"
style={styles.wrapper}
ref={this.wrapperRef}
>
<div className="modal_body" style={styles.body}>
<h2>Modal</h2>
<button onClick={this.closeModal}>Close</button>
</div>
</div>
);
}
}
Solution
The correct type is React.MouseEvent;
Which gives you the type of Reacts synthetic event.
If you have problems with event.target not being typed to what you were expecting you can do this...
const isElement = (something: any): something is HTMLElement => {
return something instanceof HTMLElement;
}
which will allow you to do this...
const takeEvent = (e: React.MouseEvent<HTMLDivElement>) => {
if(isElement(e.target)) {
// typescript will now type e.target to HTMLElement inside this block;
}
}
==== EDIT =====
instanceof
is now a recognized inbuilt type-guard in TypeScript
The more modern solution in latest version of TypeScript is.
const takeEvent = (e: React.MouseEvent<HTMLDivElement>) => {
if (!(e.target instanceof HTMLDivElement)) return;
const whattype = e.target; // HTMLDivElement
};
Answered By - Shanon Jackson
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.