I have an interface called “DataSet”, which features an optional property, which is an object with various optional event functions on it:
export interface DataSet {
colour: string;
value: number;
events?: {
onAuxClick?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onBlur?(event: React.FocusEvent<SVGPathElement, Element>, data: DataSet): void;
onClick?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onDoubleClick?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onFocus?(event: React.FocusEvent<SVGPathElement, Element>, data: DataSet): void;
onKeyDown?(event: React.KeyboardEvent<SVGPathElement>, data: DataSet): void;
onKeyPress?(event: React.KeyboardEvent<SVGPathElement>, data: DataSet): void;
onKeyUp?(event: React.KeyboardEvent<SVGPathElement>, data: DataSet): void;
onMouseDown?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onMouseEnter?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onMouseLeave?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onMouseMove?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onMouseOut?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onMouseUp?(event: React.MouseEvent<SVGPathElement, MouseEvent>, data: DataSet): void;
onPointerCancel?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerDown?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerEnter?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerLeave?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerMove?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerOut?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onPointerUp?(event: React.PointerEvent<SVGPathElement>, data: DataSet): void;
onTouchCancel?(event: React.TouchEvent<SVGPathElement>, data: DataSet): void;
onTouchEnd?(event: React.TouchEvent<SVGPathElement>, data: DataSet): void;
onTouchMove?(event: React.TouchEvent<SVGPathElement>, data: DataSet): void;
onTouchStart?(event: React.TouchEvent<SVGPathElement>, data: DataSet): void;
}
}
In a component, I iterate over an array of these “DataSet” objects to create SVGPathElements and attach those events to the element (whilst passing the “DataSet” object into the function itself)
data.map((dataEntry, index) => {
segments.push(<path
onAuxClick={(event) => dataEntry.events?.onAuxClick ? dataEntry.events?.onAuxClick(event, dataEntry) : null}
onBlur={(event) => dataEntry.events?.onBlur ? dataEntry.events?.onBlur(event, dataEntry) : null}
onClick={(event) => dataEntry.events?.onClick ? dataEntry.events?.onClick(event, dataEntry) : null}
onDoubleClick={(event) => dataEntry.events?.onDoubleClick ? dataEntry.events?.onDoubleClick(event, dataEntry) : null}
onFocus={(event) => dataEntry.events?.onFocus ? dataEntry.events?.onFocus(event, dataEntry) : null}
onKeyDown={(event) => dataEntry.events?.onKeyDown ? dataEntry.events?.onKeyDown(event, dataEntry) : null}
onKeyPress={(event) => dataEntry.events?.onKeyPress ? dataEntry.events?.onKeyPress(event, dataEntry) : null}
onKeyUp={(event) => dataEntry.events?.onKeyUp ? dataEntry.events?.onKeyUp(event, dataEntry) : null}
onMouseDown={(event) => dataEntry.events?.onMouseDown ? dataEntry.events?.onMouseDown(event, dataEntry) : null}
onMouseEnter={(event) => dataEntry.events?.onMouseEnter ? dataEntry.events?.onMouseEnter(event, dataEntry) : null}
onMouseLeave={(event) => dataEntry.events?.onMouseLeave ? dataEntry.events?.onMouseLeave(event, dataEntry) : null}
onMouseMove={(event) => dataEntry.events?.onMouseMove ? dataEntry.events?.onMouseMove(event, dataEntry) : null}
onMouseOut={(event) => dataEntry.events?.onMouseOut ? dataEntry.events?.onMouseOut(event, dataEntry) : null}
onMouseUp={(event) => dataEntry.events?.onMouseUp ? dataEntry.events?.onMouseUp(event, dataEntry) : null}
onPointerCancel={(event) => dataEntry.events?.onPointerCancel ? dataEntry.events?.onPointerCancel(event, dataEntry) : null}
onPointerDown={(event) => dataEntry.events?.onPointerDown ? dataEntry.events?.onPointerDown(event, dataEntry) : null}
onPointerEnter={(event) => dataEntry.events?.onPointerEnter ? dataEntry.events?.onPointerEnter(event, dataEntry) : null}
onPointerLeave={(event) => dataEntry.events?.onPointerLeave ? dataEntry.events?.onPointerLeave(event, dataEntry) : null}
onPointerMove={(event) => dataEntry.events?.onPointerMove ? dataEntry.events?.onPointerMove(event, dataEntry) : null}
onPointerOut={(event) => dataEntry.events?.onPointerOut ? dataEntry.events?.onPointerOut(event, dataEntry) : null}
onPointerUp={(event) => dataEntry.events?.onPointerUp ? dataEntry.events?.onPointerUp(event, dataEntry) : null}
onTouchCancel={(event) => dataEntry.events?.onTouchCancel ? dataEntry.events?.onTouchCancel(event, dataEntry) : null}
onTouchEnd={(event) => dataEntry.events?.onTouchEnd ? dataEntry.events?.onTouchEnd(event, dataEntry) : null}
onTouchMove={(event) => dataEntry.events?.onTouchMove ? dataEntry.events?.onTouchMove(event, dataEntry) : null}
onTouchStart={(event) => dataEntry.events?.onTouchStart ? dataEntry.events?.onTouchStart(event, dataEntry) : null}
/>);
})
(I’ve removed irrelevant parts of the above code)
If I add a lot of other events to the interface, it’s going to be a bit time consuming to add them explicitly to the component.
Is there an elegant way to add all of those functions to the path element, so that I can only add to the interface without needing to edit the component too? Or has my approach of defining them on the DataSet made a rod for my own back? (Passing the DataSet object to the function probably complicates matters somewhat, too)
I did try {...dataEntry.events} but that didn’t work (I think the resulting code would just be the functions without binding them to the events on the element)
As a secondary question, is there any downside to adding the functions as I have (i.e. the path element will always have a click function, but it will do nothing if it wasn’t defined on the DataSet) or is React smart enough to strip them out when the function would just return null without any further processing?